@@ -24,6 +24,43 @@ static void BackgroundRunner(void* data) {
2424 }
2525}
2626
27+ BackgroundTaskRunner::BackgroundTaskRunner (int thread_pool_size) {
28+ for (int i = 0 ; i < thread_pool_size; i++) {
29+ std::unique_ptr<uv_thread_t > t { new uv_thread_t () };
30+ if (uv_thread_create (t.get (), BackgroundRunner, &background_tasks_) != 0 )
31+ break ;
32+ threads_.push_back (std::move (t));
33+ }
34+ }
35+
36+ void BackgroundTaskRunner::PostTask (std::unique_ptr<Task> task) {
37+ background_tasks_.Push (std::move (task));
38+ }
39+
40+ void BackgroundTaskRunner::PostIdleTask (std::unique_ptr<v8::IdleTask> task) {
41+ UNREACHABLE ();
42+ }
43+
44+ void BackgroundTaskRunner::PostDelayedTask (std::unique_ptr<v8::Task> task,
45+ double delay_in_seconds) {
46+ UNREACHABLE ();
47+ }
48+
49+ void BackgroundTaskRunner::BlockingDrain () {
50+ background_tasks_.BlockingDrain ();
51+ }
52+
53+ void BackgroundTaskRunner::Shutdown () {
54+ background_tasks_.Stop ();
55+ for (size_t i = 0 ; i < threads_.size (); i++) {
56+ CHECK_EQ (0 , uv_thread_join (threads_[i].get ()));
57+ }
58+ }
59+
60+ size_t BackgroundTaskRunner::NumberOfAvailableBackgroundThreads () const {
61+ return threads_.size ();
62+ }
63+
2764PerIsolatePlatformData::PerIsolatePlatformData (
2865 v8::Isolate* isolate, uv_loop_t * loop)
2966 : isolate_(isolate), loop_(loop) {
@@ -38,17 +75,20 @@ void PerIsolatePlatformData::FlushTasks(uv_async_t* handle) {
3875 platform_data->FlushForegroundTasksInternal ();
3976}
4077
41- void PerIsolatePlatformData::CallOnForegroundThread (
42- std::unique_ptr<Task> task) {
78+ void PerIsolatePlatformData::PostIdleTask (std::unique_ptr<v8::IdleTask> task) {
79+ UNREACHABLE ();
80+ }
81+
82+ void PerIsolatePlatformData::PostTask (std::unique_ptr<Task> task) {
4383 foreground_tasks_.Push (std::move (task));
4484 uv_async_send (flush_tasks_);
4585}
4686
47- void PerIsolatePlatformData::CallDelayedOnForegroundThread (
48- std::unique_ptr<Task> task, double delay_in_seconds) {
87+ void PerIsolatePlatformData::PostDelayedTask (
88+ std::unique_ptr<Task> task, double delay_in_seconds) {
4989 std::unique_ptr<DelayedTask> delayed (new DelayedTask ());
5090 delayed->task = std::move (task);
51- delayed->platform_data = this ;
91+ delayed->platform_data = shared_from_this () ;
5292 delayed->timeout = delay_in_seconds;
5393 foreground_delayed_tasks_.Push (std::move (delayed));
5494 uv_async_send (flush_tasks_);
@@ -80,49 +120,43 @@ NodePlatform::NodePlatform(int thread_pool_size,
80120 TracingController* controller = new TracingController ();
81121 tracing_controller_.reset (controller);
82122 }
83- for (int i = 0 ; i < thread_pool_size; i++) {
84- uv_thread_t * t = new uv_thread_t ();
85- if (uv_thread_create (t, BackgroundRunner, &background_tasks_) != 0 ) {
86- delete t;
87- break ;
88- }
89- threads_.push_back (std::unique_ptr<uv_thread_t >(t));
90- }
123+ background_task_runner_ =
124+ std::make_shared<BackgroundTaskRunner>(thread_pool_size);
91125}
92126
93127void NodePlatform::RegisterIsolate (IsolateData* isolate_data, uv_loop_t * loop) {
94128 Isolate* isolate = isolate_data->isolate ();
95129 Mutex::ScopedLock lock (per_isolate_mutex_);
96- PerIsolatePlatformData* existing = per_isolate_[isolate];
97- if (existing != nullptr )
130+ std::shared_ptr< PerIsolatePlatformData> existing = per_isolate_[isolate];
131+ if (existing) {
98132 existing->ref ();
99- else
100- per_isolate_[isolate] = new PerIsolatePlatformData (isolate, loop);
133+ } else {
134+ per_isolate_[isolate] =
135+ std::make_shared<PerIsolatePlatformData>(isolate, loop);
136+ }
101137}
102138
103139void NodePlatform::UnregisterIsolate (IsolateData* isolate_data) {
104140 Isolate* isolate = isolate_data->isolate ();
105141 Mutex::ScopedLock lock (per_isolate_mutex_);
106- PerIsolatePlatformData* existing = per_isolate_[isolate];
107- CHECK_NE (existing, nullptr );
142+ std::shared_ptr< PerIsolatePlatformData> existing = per_isolate_[isolate];
143+ CHECK (existing);
108144 if (existing->unref () == 0 ) {
109- delete existing;
110145 per_isolate_.erase (isolate);
111146 }
112147}
113148
114149void NodePlatform::Shutdown () {
115- background_tasks_.Stop ();
116- for (size_t i = 0 ; i < threads_.size (); i++) {
117- CHECK_EQ (0 , uv_thread_join (threads_[i].get ()));
150+ background_task_runner_->Shutdown ();
151+
152+ {
153+ Mutex::ScopedLock lock (per_isolate_mutex_);
154+ per_isolate_.clear ();
118155 }
119- Mutex::ScopedLock lock (per_isolate_mutex_);
120- for (const auto & pair : per_isolate_)
121- delete pair.second ;
122156}
123157
124158size_t NodePlatform::NumberOfAvailableBackgroundThreads () {
125- return threads_. size ();
159+ return background_task_runner_-> NumberOfAvailableBackgroundThreads ();
126160}
127161
128162void PerIsolatePlatformData::RunForegroundTask (std::unique_ptr<Task> task) {
@@ -155,14 +189,14 @@ void PerIsolatePlatformData::CancelPendingDelayedTasks() {
155189}
156190
157191void NodePlatform::DrainBackgroundTasks (Isolate* isolate) {
158- PerIsolatePlatformData* per_isolate = ForIsolate (isolate);
192+ std::shared_ptr< PerIsolatePlatformData> per_isolate = ForIsolate (isolate);
159193
160194 do {
161195 // Right now, there is no way to drain only background tasks associated
162196 // with a specific isolate, so this sometimes does more work than
163197 // necessary. In the long run, that functionality is probably going to
164198 // be available anyway, though.
165- background_tasks_. BlockingDrain ();
199+ background_task_runner_-> BlockingDrain ();
166200 } while (per_isolate->FlushForegroundTasksInternal ());
167201}
168202
@@ -198,24 +232,25 @@ bool PerIsolatePlatformData::FlushForegroundTasksInternal() {
198232
199233void NodePlatform::CallOnBackgroundThread (Task* task,
200234 ExpectedRuntime expected_runtime) {
201- background_tasks_. Push (std::unique_ptr<Task>(task));
235+ background_task_runner_-> PostTask (std::unique_ptr<Task>(task));
202236}
203237
204- PerIsolatePlatformData* NodePlatform::ForIsolate (Isolate* isolate) {
238+ std::shared_ptr<PerIsolatePlatformData>
239+ NodePlatform::ForIsolate (Isolate* isolate) {
205240 Mutex::ScopedLock lock (per_isolate_mutex_);
206- PerIsolatePlatformData* data = per_isolate_[isolate];
207- CHECK_NE (data, nullptr );
241+ std::shared_ptr< PerIsolatePlatformData> data = per_isolate_[isolate];
242+ CHECK (data);
208243 return data;
209244}
210245
211246void NodePlatform::CallOnForegroundThread (Isolate* isolate, Task* task) {
212- ForIsolate (isolate)->CallOnForegroundThread (std::unique_ptr<Task>(task));
247+ ForIsolate (isolate)->PostTask (std::unique_ptr<Task>(task));
213248}
214249
215250void NodePlatform::CallDelayedOnForegroundThread (Isolate* isolate,
216251 Task* task,
217252 double delay_in_seconds) {
218- ForIsolate (isolate)->CallDelayedOnForegroundThread (
253+ ForIsolate (isolate)->PostDelayedTask (
219254 std::unique_ptr<Task>(task), delay_in_seconds);
220255}
221256
@@ -229,6 +264,16 @@ void NodePlatform::CancelPendingDelayedTasks(v8::Isolate* isolate) {
229264
230265bool NodePlatform::IdleTasksEnabled (Isolate* isolate) { return false ; }
231266
267+ std::shared_ptr<v8::TaskRunner>
268+ NodePlatform::GetBackgroundTaskRunner (Isolate* isolate) {
269+ return background_task_runner_;
270+ }
271+
272+ std::shared_ptr<v8::TaskRunner>
273+ NodePlatform::GetForegroundTaskRunner (Isolate* isolate) {
274+ return ForIsolate (isolate);
275+ }
276+
232277double NodePlatform::MonotonicallyIncreasingTime () {
233278 // Convert nanos to seconds.
234279 return uv_hrtime () / 1e9 ;
0 commit comments