diff options
author | Anna Henningsen <anna@addaleax.net> | 2017-11-19 14:29:08 +0100 |
---|---|---|
committer | James M Snell <jasnell@gmail.com> | 2017-11-21 07:38:03 -0800 |
commit | f005656719326bd68e12cda0c0af78756ebd11c6 (patch) | |
tree | e9f1cce83dc72664d19b0b4bd74a7223fb031541 /src/node_platform.cc | |
parent | 2540e3dacfe7ae55f4b3f2c229d8486d88a0622c (diff) | |
download | node-new-f005656719326bd68e12cda0c0af78756ebd11c6.tar.gz |
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.cc | 115 |
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; |