Skip to content

Commit 25d7c02

Browse files
ofrobotsMylesBorins
authored andcommitted
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 PR-URL: #23233 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
1 parent 808f37c commit 25d7c02

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

src/node_platform.cc

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,28 @@ using v8::Platform;
1616
using v8::Task;
1717
using v8::TracingController;
1818

19+
struct PlatformWorkerData {
20+
TaskQueue<Task>* task_queue;
21+
Mutex* platform_workers_mutex;
22+
ConditionVariable* platform_workers_ready;
23+
int* pending_platform_workers;
24+
int id;
25+
};
26+
1927
static void BackgroundRunner(void* data) {
28+
std::unique_ptr<PlatformWorkerData>
29+
worker_data(static_cast<PlatformWorkerData*>(data));
2030
TRACE_EVENT_METADATA1("__metadata", "thread_name", "name",
2131
"BackgroundTaskRunner");
22-
TaskQueue<Task> *background_tasks = static_cast<TaskQueue<Task> *>(data);
32+
33+
// Notify the main thread that the platform worker is ready.
34+
{
35+
Mutex::ScopedLock lock(*worker_data->platform_workers_mutex);
36+
(*worker_data->pending_platform_workers)--;
37+
worker_data->platform_workers_ready->Signal(lock);
38+
}
39+
40+
TaskQueue<Task>* background_tasks = worker_data->task_queue;
2341
while (std::unique_ptr<Task> task = background_tasks->BlockingPop()) {
2442
task->Run();
2543
background_tasks->NotifyOfCompletion();
@@ -144,15 +162,29 @@ class BackgroundTaskRunner::DelayedTaskScheduler {
144162
};
145163

146164
BackgroundTaskRunner::BackgroundTaskRunner(int thread_pool_size) {
165+
Mutex::ScopedLock lock(platform_workers_mutex_);
166+
pending_platform_workers_ = thread_pool_size;
167+
147168
delayed_task_scheduler_.reset(
148169
new DelayedTaskScheduler(&background_tasks_));
149170
threads_.push_back(delayed_task_scheduler_->Start());
171+
150172
for (int i = 0; i < thread_pool_size; i++) {
173+
PlatformWorkerData* worker_data = new PlatformWorkerData{
174+
&background_tasks_, &platform_workers_mutex_,
175+
&platform_workers_ready_, &pending_platform_workers_, i
176+
};
151177
std::unique_ptr<uv_thread_t> t { new uv_thread_t() };
152-
if (uv_thread_create(t.get(), BackgroundRunner, &background_tasks_) != 0)
178+
if (uv_thread_create(t.get(), BackgroundRunner, worker_data) != 0)
153179
break;
154180
threads_.push_back(std::move(t));
155181
}
182+
183+
// Wait for platform workers to initialize before continuing with the
184+
// bootstrap.
185+
while (pending_platform_workers_ > 0) {
186+
platform_workers_ready_.Wait(lock);
187+
}
156188
}
157189

158190
void BackgroundTaskRunner::PostTask(std::unique_ptr<Task> task) {

src/node_platform.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,18 @@ class BackgroundTaskRunner : public v8::TaskRunner {
110110
void Shutdown();
111111

112112
size_t NumberOfAvailableBackgroundThreads() const;
113+
113114
private:
114115
TaskQueue<v8::Task> background_tasks_;
115116

116117
class DelayedTaskScheduler;
117118
std::unique_ptr<DelayedTaskScheduler> delayed_task_scheduler_;
118119

119120
std::vector<std::unique_ptr<uv_thread_t>> threads_;
121+
122+
Mutex platform_workers_mutex_;
123+
ConditionVariable platform_workers_ready_;
124+
int pending_platform_workers_;
120125
};
121126

122127
class NodePlatform : public MultiIsolatePlatform {

0 commit comments

Comments
 (0)