Skip to content

Commit 3afca3a

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: #23065
1 parent 5d8373a commit 3afca3a

File tree

1 file changed

+35
-2
lines changed

1 file changed

+35
-2
lines changed

src/node_platform.cc

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

1919
namespace {
2020

21+
static Mutex platform_workers_mutex;
22+
static ConditionVariable platform_workers_ready;
23+
static int pending_platform_workers;
24+
25+
struct PlatformWorkerData {
26+
TaskQueue<Task>* task_queue;
27+
int id;
28+
};
29+
2130
static void PlatformWorkerThread(void* data) {
31+
std::unique_ptr<PlatformWorkerData>
32+
worker_data(static_cast<PlatformWorkerData*>(data));
33+
34+
TaskQueue<Task>* pending_worker_tasks = worker_data->task_queue;
2235
TRACE_EVENT_METADATA1("__metadata", "thread_name", "name",
2336
"PlatformWorkerThread");
24-
TaskQueue<Task>* pending_worker_tasks = static_cast<TaskQueue<Task>*>(data);
37+
38+
// Notify the main thread that the platform worker is ready.
39+
{
40+
Mutex::ScopedLock lock(platform_workers_mutex);
41+
pending_platform_workers--;
42+
platform_workers_ready.Signal(lock);
43+
}
44+
2545
while (std::unique_ptr<Task> task = pending_worker_tasks->BlockingPop()) {
2646
task->Run();
2747
pending_worker_tasks->NotifyOfCompletion();
@@ -148,17 +168,30 @@ class WorkerThreadsTaskRunner::DelayedTaskScheduler {
148168
};
149169

150170
WorkerThreadsTaskRunner::WorkerThreadsTaskRunner(int thread_pool_size) {
171+
Mutex::ScopedLock lock(platform_workers_mutex);
172+
pending_platform_workers = thread_pool_size;
173+
151174
delayed_task_scheduler_.reset(
152175
new DelayedTaskScheduler(&pending_worker_tasks_));
153176
threads_.push_back(delayed_task_scheduler_->Start());
177+
154178
for (int i = 0; i < thread_pool_size; i++) {
179+
PlatformWorkerData* worker_data = new PlatformWorkerData{
180+
&pending_worker_tasks_, i
181+
};
155182
std::unique_ptr<uv_thread_t> t { new uv_thread_t() };
156183
if (uv_thread_create(t.get(), PlatformWorkerThread,
157-
&pending_worker_tasks_) != 0) {
184+
worker_data) != 0) {
158185
break;
159186
}
160187
threads_.push_back(std::move(t));
161188
}
189+
190+
// Wait for platform workers to initialize before continuing with the
191+
// bootstrap.
192+
while (pending_platform_workers > 0) {
193+
platform_workers_ready.Wait(lock);
194+
}
162195
}
163196

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

0 commit comments

Comments
 (0)