Skip to content

Commit a4ae74a

Browse files
Gabriel Charetteblattersturm
authored andcommitted
src: use modern v8::Platform worker threads APIs
Precursor to removing deprecated APIs on the v8 side @ https://chromium-review.googlesource.com/c/v8/v8/+/1045310 PR-URL: nodejs#21079 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Yang Guo <yangguo@chromium.org>
1 parent 5de5155 commit a4ae74a

File tree

4 files changed

+58
-56
lines changed

4 files changed

+58
-56
lines changed

src/node.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ static struct {
315315
}
316316

317317
void DrainVMTasks(Isolate* isolate) {
318-
platform_->DrainBackgroundTasks(isolate);
318+
platform_->DrainTasks(isolate);
319319
}
320320

321321
void CancelVMTasks(Isolate* isolate) {

src/node.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,11 @@ class Environment;
217217
class MultiIsolatePlatform : public v8::Platform {
218218
public:
219219
virtual ~MultiIsolatePlatform() { }
220-
virtual void DrainBackgroundTasks(v8::Isolate* isolate) = 0;
220+
// Returns true if work was dispatched or executed. New tasks that are
221+
// posted during flushing of the queue are postponed until the next
222+
// flushing.
223+
virtual bool FlushForegroundTasks(v8::Isolate* isolate) = 0;
224+
virtual void DrainTasks(v8::Isolate* isolate) = 0;
221225
virtual void CancelPendingDelayedTasks(v8::Isolate* isolate) = 0;
222226

223227
// These will be called by the `IsolateData` creation/destruction functions.

src/node_platform.cc

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -20,50 +20,52 @@ using v8::Platform;
2020
using v8::Task;
2121
using v8::TracingController;
2222

23-
static void BackgroundRunner(void *data) {
23+
namespace {
24+
25+
static void WorkerThreadMain(void* data) {
2426
TRACE_EVENT_METADATA1("__metadata", "thread_name", "name",
2527
"BackgroundTaskRunner");
26-
TaskQueue<Task> *background_tasks = static_cast<TaskQueue<Task> *>(data);
27-
while (std::unique_ptr<Task> task = background_tasks->BlockingPop()) {
28+
TaskQueue<Task>* pending_worker_tasks = static_cast<TaskQueue<Task>*>(data);
29+
while (std::unique_ptr<Task> task = pending_worker_tasks->BlockingPop()) {
2830
task->Run();
29-
background_tasks->NotifyOfCompletion();
31+
pending_worker_tasks->NotifyOfCompletion();
3032
}
3133
}
3234

33-
BackgroundTaskRunner::BackgroundTaskRunner(int thread_pool_size) {
35+
} // namespace
36+
37+
WorkerThreadsTaskRunner::WorkerThreadsTaskRunner(int thread_pool_size) {
3438
for (int i = 0; i < thread_pool_size; i++) {
3539
std::unique_ptr<uv_thread_t> t { new uv_thread_t() };
36-
if (uv_thread_create(t.get(), BackgroundRunner, &background_tasks_) != 0)
40+
if (uv_thread_create(t.get(), WorkerThreadMain,
41+
&pending_worker_tasks_) != 0) {
3742
break;
43+
}
3844
threads_.push_back(std::move(t));
3945
}
4046
}
4147

42-
void BackgroundTaskRunner::PostTask(std::unique_ptr<Task> task) {
43-
background_tasks_.Push(std::move(task));
44-
}
45-
46-
void BackgroundTaskRunner::PostIdleTask(std::unique_ptr<v8::IdleTask> task) {
47-
UNREACHABLE();
48+
void WorkerThreadsTaskRunner::PostTask(std::unique_ptr<Task> task) {
49+
pending_worker_tasks_.Push(std::move(task));
4850
}
4951

50-
void BackgroundTaskRunner::PostDelayedTask(std::unique_ptr<v8::Task> task,
51-
double delay_in_seconds) {
52+
void WorkerThreadsTaskRunner::PostDelayedTask(std::unique_ptr<v8::Task> task,
53+
double delay_in_seconds) {
5254
UNREACHABLE();
5355
}
5456

55-
void BackgroundTaskRunner::BlockingDrain() {
56-
background_tasks_.BlockingDrain();
57+
void WorkerThreadsTaskRunner::BlockingDrain() {
58+
pending_worker_tasks_.BlockingDrain();
5759
}
5860

59-
void BackgroundTaskRunner::Shutdown() {
60-
background_tasks_.Stop();
61+
void WorkerThreadsTaskRunner::Shutdown() {
62+
pending_worker_tasks_.Stop();
6163
for (size_t i = 0; i < threads_.size(); i++) {
6264
CHECK_EQ(0, uv_thread_join(threads_[i].get()));
6365
}
6466
}
6567

66-
size_t BackgroundTaskRunner::NumberOfAvailableBackgroundThreads() const {
68+
int WorkerThreadsTaskRunner::NumberOfWorkerThreads() const {
6769
return threads_.size();
6870
}
6971

@@ -136,8 +138,8 @@ NodePlatform::NodePlatform(int thread_pool_size,
136138
TracingController* controller = new TracingController();
137139
tracing_controller_.reset(controller);
138140
}
139-
background_task_runner_ =
140-
std::make_shared<BackgroundTaskRunner>(thread_pool_size);
141+
worker_thread_task_runner_ =
142+
std::make_shared<WorkerThreadsTaskRunner>(thread_pool_size);
141143
}
142144

143145
void NodePlatform::RegisterIsolate(IsolateData* isolate_data, uv_loop_t* loop) {
@@ -165,16 +167,16 @@ void NodePlatform::UnregisterIsolate(IsolateData* isolate_data) {
165167
}
166168

167169
void NodePlatform::Shutdown() {
168-
background_task_runner_->Shutdown();
170+
worker_thread_task_runner_->Shutdown();
169171

170172
{
171173
Mutex::ScopedLock lock(per_isolate_mutex_);
172174
per_isolate_.clear();
173175
}
174176
}
175177

176-
size_t NodePlatform::NumberOfAvailableBackgroundThreads() {
177-
return background_task_runner_->NumberOfAvailableBackgroundThreads();
178+
int NodePlatform::NumberOfWorkerThreads() {
179+
return worker_thread_task_runner_->NumberOfWorkerThreads();
178180
}
179181

180182
void PerIsolatePlatformData::RunForegroundTask(std::unique_ptr<Task> task) {
@@ -206,15 +208,12 @@ void PerIsolatePlatformData::CancelPendingDelayedTasks() {
206208
scheduled_delayed_tasks_.clear();
207209
}
208210

209-
void NodePlatform::DrainBackgroundTasks(Isolate* isolate) {
211+
void NodePlatform::DrainTasks(Isolate* isolate) {
210212
std::shared_ptr<PerIsolatePlatformData> per_isolate = ForIsolate(isolate);
211213

212214
do {
213-
// Right now, there is no way to drain only background tasks associated
214-
// with a specific isolate, so this sometimes does more work than
215-
// necessary. In the long run, that functionality is probably going to
216-
// be available anyway, though.
217-
background_task_runner_->BlockingDrain();
215+
// Worker tasks aren't associated with an Isolate.
216+
worker_thread_task_runner_->BlockingDrain();
218217
} while (per_isolate->FlushForegroundTasksInternal());
219218
}
220219

@@ -254,11 +253,17 @@ bool PerIsolatePlatformData::FlushForegroundTasksInternal() {
254253
return did_work;
255254
}
256255

257-
void NodePlatform::CallOnBackgroundThread(Task* task,
258-
ExpectedRuntime expected_runtime) {
259-
background_task_runner_->PostTask(std::unique_ptr<Task>(task));
256+
void NodePlatform::CallOnWorkerThread(std::unique_ptr<v8::Task> task) {
257+
worker_thread_task_runner_->PostTask(std::move(task));
260258
}
261259

260+
void NodePlatform::CallDelayedOnWorkerThread(std::unique_ptr<v8::Task> task,
261+
double delay_in_seconds) {
262+
worker_thread_task_runner_->PostDelayedTask(std::move(task),
263+
delay_in_seconds);
264+
}
265+
266+
262267
std::shared_ptr<PerIsolatePlatformData>
263268
NodePlatform::ForIsolate(Isolate* isolate) {
264269
Mutex::ScopedLock lock(per_isolate_mutex_);
@@ -288,11 +293,6 @@ void NodePlatform::CancelPendingDelayedTasks(v8::Isolate* isolate) {
288293

289294
bool NodePlatform::IdleTasksEnabled(Isolate* isolate) { return false; }
290295

291-
std::shared_ptr<v8::TaskRunner>
292-
NodePlatform::GetBackgroundTaskRunner(Isolate* isolate) {
293-
return background_task_runner_;
294-
}
295-
296296
std::shared_ptr<v8::TaskRunner>
297297
NodePlatform::GetForegroundTaskRunner(Isolate* isolate) {
298298
return ForIsolate(isolate);

src/node_platform.h

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -93,23 +93,22 @@ class PerIsolatePlatformData :
9393
std::vector<DelayedTaskPointer> scheduled_delayed_tasks_;
9494
};
9595

96-
// This acts as the single background task runner for all Isolates.
97-
class BackgroundTaskRunner : public v8::TaskRunner {
96+
// This acts as the single worker thread task runner for all Isolates.
97+
class WorkerThreadsTaskRunner {
9898
public:
99-
explicit BackgroundTaskRunner(int thread_pool_size);
99+
explicit WorkerThreadsTaskRunner(int thread_pool_size);
100100

101-
void PostTask(std::unique_ptr<v8::Task> task) override;
102-
void PostIdleTask(std::unique_ptr<v8::IdleTask> task) override;
101+
void PostTask(std::unique_ptr<v8::Task> task);
103102
void PostDelayedTask(std::unique_ptr<v8::Task> task,
104-
double delay_in_seconds) override;
105-
bool IdleTasksEnabled() override { return false; };
103+
double delay_in_seconds);
106104

107105
void BlockingDrain();
108106
void Shutdown();
109107

110-
size_t NumberOfAvailableBackgroundThreads() const;
108+
int NumberOfWorkerThreads() const;
109+
111110
private:
112-
TaskQueue<v8::Task> background_tasks_;
111+
TaskQueue<v8::Task> pending_worker_tasks_;
113112
std::vector<std::unique_ptr<uv_thread_t>> threads_;
114113
};
115114

@@ -118,14 +117,15 @@ class NodePlatform : public MultiIsolatePlatform {
118117
NodePlatform(int thread_pool_size, v8::TracingController* tracing_controller);
119118
virtual ~NodePlatform() {}
120119

121-
void DrainBackgroundTasks(v8::Isolate* isolate) override;
120+
void DrainTasks(v8::Isolate* isolate) override;
122121
void CancelPendingDelayedTasks(v8::Isolate* isolate) override;
123122
void Shutdown();
124123

125124
// v8::Platform implementation.
126-
size_t NumberOfAvailableBackgroundThreads() override;
127-
void CallOnBackgroundThread(v8::Task* task,
128-
ExpectedRuntime expected_runtime) override;
125+
int NumberOfWorkerThreads() override;
126+
void CallOnWorkerThread(std::unique_ptr<v8::Task> task) override;
127+
void CallDelayedOnWorkerThread(std::unique_ptr<v8::Task> task,
128+
double delay_in_seconds) override;
129129
void CallOnForegroundThread(v8::Isolate* isolate, v8::Task* task) override;
130130
void CallDelayedOnForegroundThread(v8::Isolate* isolate, v8::Task* task,
131131
double delay_in_seconds) override;
@@ -142,8 +142,6 @@ class NodePlatform : public MultiIsolatePlatform {
142142
void RegisterIsolate(IsolateData* isolate_data, uv_loop_t* loop) override;
143143
void UnregisterIsolate(IsolateData* isolate_data) override;
144144

145-
std::shared_ptr<v8::TaskRunner> GetBackgroundTaskRunner(
146-
v8::Isolate* isolate) override;
147145
std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner(
148146
v8::Isolate* isolate) override;
149147

@@ -155,7 +153,7 @@ class NodePlatform : public MultiIsolatePlatform {
155153
std::shared_ptr<PerIsolatePlatformData>> per_isolate_;
156154

157155
std::unique_ptr<v8::TracingController> tracing_controller_;
158-
std::shared_ptr<BackgroundTaskRunner> background_task_runner_;
156+
std::shared_ptr<WorkerThreadsTaskRunner> worker_thread_task_runner_;
159157
};
160158

161159
} // namespace node

0 commit comments

Comments
 (0)