@@ -24,6 +24,43 @@ static void BackgroundRunner(void* data) {
24
24
}
25
25
}
26
26
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
+
27
64
PerIsolatePlatformData::PerIsolatePlatformData (
28
65
v8::Isolate* isolate, uv_loop_t * loop)
29
66
: isolate_(isolate), loop_(loop) {
@@ -38,17 +75,20 @@ void PerIsolatePlatformData::FlushTasks(uv_async_t* handle) {
38
75
platform_data->FlushForegroundTasksInternal ();
39
76
}
40
77
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) {
43
83
foreground_tasks_.Push (std::move (task));
44
84
uv_async_send (flush_tasks_);
45
85
}
46
86
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) {
49
89
std::unique_ptr<DelayedTask> delayed (new DelayedTask ());
50
90
delayed->task = std::move (task);
51
- delayed->platform_data = this ;
91
+ delayed->platform_data = shared_from_this () ;
52
92
delayed->timeout = delay_in_seconds;
53
93
foreground_delayed_tasks_.Push (std::move (delayed));
54
94
uv_async_send (flush_tasks_);
@@ -80,49 +120,43 @@ NodePlatform::NodePlatform(int thread_pool_size,
80
120
TracingController* controller = new TracingController ();
81
121
tracing_controller_.reset (controller);
82
122
}
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);
91
125
}
92
126
93
127
void NodePlatform::RegisterIsolate (IsolateData* isolate_data, uv_loop_t * loop) {
94
128
Isolate* isolate = isolate_data->isolate ();
95
129
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) {
98
132
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
+ }
101
137
}
102
138
103
139
void NodePlatform::UnregisterIsolate (IsolateData* isolate_data) {
104
140
Isolate* isolate = isolate_data->isolate ();
105
141
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);
108
144
if (existing->unref () == 0 ) {
109
- delete existing;
110
145
per_isolate_.erase (isolate);
111
146
}
112
147
}
113
148
114
149
void 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 ();
118
155
}
119
- Mutex::ScopedLock lock (per_isolate_mutex_);
120
- for (const auto & pair : per_isolate_)
121
- delete pair.second ;
122
156
}
123
157
124
158
size_t NodePlatform::NumberOfAvailableBackgroundThreads () {
125
- return threads_. size ();
159
+ return background_task_runner_-> NumberOfAvailableBackgroundThreads ();
126
160
}
127
161
128
162
void PerIsolatePlatformData::RunForegroundTask (std::unique_ptr<Task> task) {
@@ -155,14 +189,14 @@ void PerIsolatePlatformData::CancelPendingDelayedTasks() {
155
189
}
156
190
157
191
void NodePlatform::DrainBackgroundTasks (Isolate* isolate) {
158
- PerIsolatePlatformData* per_isolate = ForIsolate (isolate);
192
+ std::shared_ptr< PerIsolatePlatformData> per_isolate = ForIsolate (isolate);
159
193
160
194
do {
161
195
// Right now, there is no way to drain only background tasks associated
162
196
// with a specific isolate, so this sometimes does more work than
163
197
// necessary. In the long run, that functionality is probably going to
164
198
// be available anyway, though.
165
- background_tasks_. BlockingDrain ();
199
+ background_task_runner_-> BlockingDrain ();
166
200
} while (per_isolate->FlushForegroundTasksInternal ());
167
201
}
168
202
@@ -198,24 +232,25 @@ bool PerIsolatePlatformData::FlushForegroundTasksInternal() {
198
232
199
233
void NodePlatform::CallOnBackgroundThread (Task* task,
200
234
ExpectedRuntime expected_runtime) {
201
- background_tasks_. Push (std::unique_ptr<Task>(task));
235
+ background_task_runner_-> PostTask (std::unique_ptr<Task>(task));
202
236
}
203
237
204
- PerIsolatePlatformData* NodePlatform::ForIsolate (Isolate* isolate) {
238
+ std::shared_ptr<PerIsolatePlatformData>
239
+ NodePlatform::ForIsolate (Isolate* isolate) {
205
240
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);
208
243
return data;
209
244
}
210
245
211
246
void NodePlatform::CallOnForegroundThread (Isolate* isolate, Task* task) {
212
- ForIsolate (isolate)->CallOnForegroundThread (std::unique_ptr<Task>(task));
247
+ ForIsolate (isolate)->PostTask (std::unique_ptr<Task>(task));
213
248
}
214
249
215
250
void NodePlatform::CallDelayedOnForegroundThread (Isolate* isolate,
216
251
Task* task,
217
252
double delay_in_seconds) {
218
- ForIsolate (isolate)->CallDelayedOnForegroundThread (
253
+ ForIsolate (isolate)->PostDelayedTask (
219
254
std::unique_ptr<Task>(task), delay_in_seconds);
220
255
}
221
256
@@ -229,6 +264,16 @@ void NodePlatform::CancelPendingDelayedTasks(v8::Isolate* isolate) {
229
264
230
265
bool NodePlatform::IdleTasksEnabled (Isolate* isolate) { return false ; }
231
266
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
+
232
277
double NodePlatform::MonotonicallyIncreasingTime () {
233
278
// Convert nanos to seconds.
234
279
return uv_hrtime () / 1e9 ;
0 commit comments