Skip to content

Commit f0db592

Browse files
committed
src: ready background workers before bootstrap
Make sure background workers are ready before proceeding with the bootstrap or post-bootstrap execution of any code that may trigger `process.exit()`. Fixes: nodejs#23065
1 parent 32bd197 commit f0db592

File tree

1 file changed

+29
-2
lines changed

1 file changed

+29
-2
lines changed

src/node_platform.cc

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,23 @@ using v8::TracingController;
1818

1919
namespace {
2020

21+
struct PlatformWorkerData {
22+
TaskQueue<Task>* task_queue;
23+
uv_barrier_t* barrier;
24+
int id;
25+
};
26+
2127
static void PlatformWorkerThread(void* data) {
28+
PlatformWorkerData* worker_data = static_cast<PlatformWorkerData*>(data);
29+
TaskQueue<Task>* pending_worker_tasks = worker_data->task_queue;
2230
TRACE_EVENT_METADATA1("__metadata", "thread_name", "name",
2331
"PlatformWorkerThread");
24-
TaskQueue<Task>* pending_worker_tasks = static_cast<TaskQueue<Task>*>(data);
32+
33+
if (uv_barrier_wait(worker_data->barrier) > 0) {
34+
uv_barrier_destroy(worker_data->barrier);
35+
delete worker_data->barrier;
36+
worker_data->barrier = nullptr;
37+
}
2538
while (std::unique_ptr<Task> task = pending_worker_tasks->BlockingPop()) {
2639
task->Run();
2740
pending_worker_tasks->NotifyOfCompletion();
@@ -148,17 +161,31 @@ class WorkerThreadsTaskRunner::DelayedTaskScheduler {
148161
};
149162

150163
WorkerThreadsTaskRunner::WorkerThreadsTaskRunner(int thread_pool_size) {
164+
uv_barrier_t* barrier = new uv_barrier_t;
165+
uv_barrier_init(barrier, thread_pool_size + 1);
166+
151167
delayed_task_scheduler_.reset(
152168
new DelayedTaskScheduler(&pending_worker_tasks_));
153169
threads_.push_back(delayed_task_scheduler_->Start());
170+
154171
for (int i = 0; i < thread_pool_size; i++) {
172+
// FIXME(ofrobots): need to delete upon shutdown.
173+
PlatformWorkerData* worker_data = new PlatformWorkerData{
174+
&pending_worker_tasks_, barrier, i
175+
};
155176
std::unique_ptr<uv_thread_t> t { new uv_thread_t() };
156177
if (uv_thread_create(t.get(), PlatformWorkerThread,
157-
&pending_worker_tasks_) != 0) {
178+
worker_data) != 0) {
158179
break;
159180
}
160181
threads_.push_back(std::move(t));
161182
}
183+
184+
// Wait for all the worker threads to be initialized.
185+
if (uv_barrier_wait(barrier) > 0) {
186+
uv_barrier_destroy(barrier);
187+
delete barrier;
188+
}
162189
}
163190

164191
void WorkerThreadsTaskRunner::PostTask(std::unique_ptr<Task> task) {

0 commit comments

Comments
 (0)