summaryrefslogtreecommitdiff
path: root/src/node_platform.cc
diff options
context:
space:
mode:
authorAnna Henningsen <anna@addaleax.net>2017-11-19 14:29:08 +0100
committerJames M Snell <jasnell@gmail.com>2017-11-21 07:38:03 -0800
commitf005656719326bd68e12cda0c0af78756ebd11c6 (patch)
treee9f1cce83dc72664d19b0b4bd74a7223fb031541 /src/node_platform.cc
parent2540e3dacfe7ae55f4b3f2c229d8486d88a0622c (diff)
downloadandroid-node-v8-f005656719326bd68e12cda0c0af78756ebd11c6.tar.gz
android-node-v8-f005656719326bd68e12cda0c0af78756ebd11c6.tar.bz2
android-node-v8-f005656719326bd68e12cda0c0af78756ebd11c6.zip
src: implement v8::TaskRunner API in NodePlatform
V8 is switching APIs for scheduling tasks. Implement the new APIs. Fixes: https://github.com/nodejs/node-v8/issues/24 Refs: https://github.com/v8/v8/commit/c690f54d9580243c53f7d892fcff1ce6bae4bfc0 PR-URL: https://github.com/nodejs/node/pull/17134 Fixes: https://github.com/nodejs/node-v8/issues/24 Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'src/node_platform.cc')
-rw-r--r--src/node_platform.cc115
1 files changed, 80 insertions, 35 deletions
diff --git a/src/node_platform.cc b/src/node_platform.cc
index 0c50e8468d..65d1ef6c5d 100644
--- a/src/node_platform.cc
+++ b/src/node_platform.cc
@@ -24,6 +24,43 @@ static void BackgroundRunner(void* data) {
}
}
+BackgroundTaskRunner::BackgroundTaskRunner(int thread_pool_size) {
+ for (int i = 0; i < thread_pool_size; i++) {
+ std::unique_ptr<uv_thread_t> t { new uv_thread_t() };
+ if (uv_thread_create(t.get(), BackgroundRunner, &background_tasks_) != 0)
+ break;
+ threads_.push_back(std::move(t));
+ }
+}
+
+void BackgroundTaskRunner::PostTask(std::unique_ptr<Task> task) {
+ background_tasks_.Push(std::move(task));
+}
+
+void BackgroundTaskRunner::PostIdleTask(std::unique_ptr<v8::IdleTask> task) {
+ UNREACHABLE();
+}
+
+void BackgroundTaskRunner::PostDelayedTask(std::unique_ptr<v8::Task> task,
+ double delay_in_seconds) {
+ UNREACHABLE();
+}
+
+void BackgroundTaskRunner::BlockingDrain() {
+ background_tasks_.BlockingDrain();
+}
+
+void BackgroundTaskRunner::Shutdown() {
+ background_tasks_.Stop();
+ for (size_t i = 0; i < threads_.size(); i++) {
+ CHECK_EQ(0, uv_thread_join(threads_[i].get()));
+ }
+}
+
+size_t BackgroundTaskRunner::NumberOfAvailableBackgroundThreads() const {
+ return threads_.size();
+}
+
PerIsolatePlatformData::PerIsolatePlatformData(
v8::Isolate* isolate, uv_loop_t* loop)
: isolate_(isolate), loop_(loop) {
@@ -38,17 +75,20 @@ void PerIsolatePlatformData::FlushTasks(uv_async_t* handle) {
platform_data->FlushForegroundTasksInternal();
}
-void PerIsolatePlatformData::CallOnForegroundThread(
- std::unique_ptr<Task> task) {
+void PerIsolatePlatformData::PostIdleTask(std::unique_ptr<v8::IdleTask> task) {
+ UNREACHABLE();
+}
+
+void PerIsolatePlatformData::PostTask(std::unique_ptr<Task> task) {
foreground_tasks_.Push(std::move(task));
uv_async_send(flush_tasks_);
}
-void PerIsolatePlatformData::CallDelayedOnForegroundThread(
- std::unique_ptr<Task> task, double delay_in_seconds) {
+void PerIsolatePlatformData::PostDelayedTask(
+ std::unique_ptr<Task> task, double delay_in_seconds) {
std::unique_ptr<DelayedTask> delayed(new DelayedTask());
delayed->task = std::move(task);
- delayed->platform_data = this;
+ delayed->platform_data = shared_from_this();
delayed->timeout = delay_in_seconds;
foreground_delayed_tasks_.Push(std::move(delayed));
uv_async_send(flush_tasks_);
@@ -80,49 +120,43 @@ NodePlatform::NodePlatform(int thread_pool_size,
TracingController* controller = new TracingController();
tracing_controller_.reset(controller);
}
- for (int i = 0; i < thread_pool_size; i++) {
- uv_thread_t* t = new uv_thread_t();
- if (uv_thread_create(t, BackgroundRunner, &background_tasks_) != 0) {
- delete t;
- break;
- }
- threads_.push_back(std::unique_ptr<uv_thread_t>(t));
- }
+ background_task_runner_ =
+ std::make_shared<BackgroundTaskRunner>(thread_pool_size);
}
void NodePlatform::RegisterIsolate(IsolateData* isolate_data, uv_loop_t* loop) {
Isolate* isolate = isolate_data->isolate();
Mutex::ScopedLock lock(per_isolate_mutex_);
- PerIsolatePlatformData* existing = per_isolate_[isolate];
- if (existing != nullptr)
+ std::shared_ptr<PerIsolatePlatformData> existing = per_isolate_[isolate];
+ if (existing) {
existing->ref();
- else
- per_isolate_[isolate] = new PerIsolatePlatformData(isolate, loop);
+ } else {
+ per_isolate_[isolate] =
+ std::make_shared<PerIsolatePlatformData>(isolate, loop);
+ }
}
void NodePlatform::UnregisterIsolate(IsolateData* isolate_data) {
Isolate* isolate = isolate_data->isolate();
Mutex::ScopedLock lock(per_isolate_mutex_);
- PerIsolatePlatformData* existing = per_isolate_[isolate];
- CHECK_NE(existing, nullptr);
+ std::shared_ptr<PerIsolatePlatformData> existing = per_isolate_[isolate];
+ CHECK(existing);
if (existing->unref() == 0) {
- delete existing;
per_isolate_.erase(isolate);
}
}
void NodePlatform::Shutdown() {
- background_tasks_.Stop();
- for (size_t i = 0; i < threads_.size(); i++) {
- CHECK_EQ(0, uv_thread_join(threads_[i].get()));
+ background_task_runner_->Shutdown();
+
+ {
+ Mutex::ScopedLock lock(per_isolate_mutex_);
+ per_isolate_.clear();
}
- Mutex::ScopedLock lock(per_isolate_mutex_);
- for (const auto& pair : per_isolate_)
- delete pair.second;
}
size_t NodePlatform::NumberOfAvailableBackgroundThreads() {
- return threads_.size();
+ return background_task_runner_->NumberOfAvailableBackgroundThreads();
}
void PerIsolatePlatformData::RunForegroundTask(std::unique_ptr<Task> task) {
@@ -155,14 +189,14 @@ void PerIsolatePlatformData::CancelPendingDelayedTasks() {
}
void NodePlatform::DrainBackgroundTasks(Isolate* isolate) {
- PerIsolatePlatformData* per_isolate = ForIsolate(isolate);
+ std::shared_ptr<PerIsolatePlatformData> per_isolate = ForIsolate(isolate);
do {
// Right now, there is no way to drain only background tasks associated
// with a specific isolate, so this sometimes does more work than
// necessary. In the long run, that functionality is probably going to
// be available anyway, though.
- background_tasks_.BlockingDrain();
+ background_task_runner_->BlockingDrain();
} while (per_isolate->FlushForegroundTasksInternal());
}
@@ -198,24 +232,25 @@ bool PerIsolatePlatformData::FlushForegroundTasksInternal() {
void NodePlatform::CallOnBackgroundThread(Task* task,
ExpectedRuntime expected_runtime) {
- background_tasks_.Push(std::unique_ptr<Task>(task));
+ background_task_runner_->PostTask(std::unique_ptr<Task>(task));
}
-PerIsolatePlatformData* NodePlatform::ForIsolate(Isolate* isolate) {
+std::shared_ptr<PerIsolatePlatformData>
+NodePlatform::ForIsolate(Isolate* isolate) {
Mutex::ScopedLock lock(per_isolate_mutex_);
- PerIsolatePlatformData* data = per_isolate_[isolate];
- CHECK_NE(data, nullptr);
+ std::shared_ptr<PerIsolatePlatformData> data = per_isolate_[isolate];
+ CHECK(data);
return data;
}
void NodePlatform::CallOnForegroundThread(Isolate* isolate, Task* task) {
- ForIsolate(isolate)->CallOnForegroundThread(std::unique_ptr<Task>(task));
+ ForIsolate(isolate)->PostTask(std::unique_ptr<Task>(task));
}
void NodePlatform::CallDelayedOnForegroundThread(Isolate* isolate,
Task* task,
double delay_in_seconds) {
- ForIsolate(isolate)->CallDelayedOnForegroundThread(
+ ForIsolate(isolate)->PostDelayedTask(
std::unique_ptr<Task>(task), delay_in_seconds);
}
@@ -229,6 +264,16 @@ void NodePlatform::CancelPendingDelayedTasks(v8::Isolate* isolate) {
bool NodePlatform::IdleTasksEnabled(Isolate* isolate) { return false; }
+std::shared_ptr<v8::TaskRunner>
+NodePlatform::GetBackgroundTaskRunner(Isolate* isolate) {
+ return background_task_runner_;
+}
+
+std::shared_ptr<v8::TaskRunner>
+NodePlatform::GetForegroundTaskRunner(Isolate* isolate) {
+ return ForIsolate(isolate);
+}
+
double NodePlatform::MonotonicallyIncreasingTime() {
// Convert nanos to seconds.
return uv_hrtime() / 1e9;