diff options
author | Anna Henningsen <anna@addaleax.net> | 2019-03-02 01:35:54 +0300 |
---|---|---|
committer | Anna Henningsen <anna@addaleax.net> | 2019-03-13 03:12:56 +0300 |
commit | 6d9aa73b1f2a0b053e39d743b1ddf382d35adfad (patch) | |
tree | 3254de3bb6292f36c4458f06f28a663614df924f /src/node_platform.cc | |
parent | 377c5835e8bfcd04273f24a244b2ba4aff76a27c (diff) |
src: clean up MultiIsolatePlatform interface
- Since this was introduced, V8 has effectively started requiring
that the platform knows of the `Isolate*` before we (or an embedder)
create our `IsolateData` structure; therefore, (un)registering it
from the `IsolateData` constructor/destructor doesn’t make much
sense anymore.
- Instead, we can require that the register/unregister functions
are only called once, simplifying the implementation a bit.
- Add a callback that we can use to know when the platform has
cleaned up its resources associated with a given `Isolate`.
In particular, this means that in the Worker code, we don’t need
to rely on what are essentially guesses about the number of event
loop turns that we need in order to have everything cleaned up.
PR-URL: https://github.com/nodejs/node/pull/26384
Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Diffstat (limited to 'src/node_platform.cc')
-rw-r--r-- | src/node_platform.cc | 45 |
1 files changed, 27 insertions, 18 deletions
diff --git a/src/node_platform.cc b/src/node_platform.cc index ba5ca794c06..bb645029196 100644 --- a/src/node_platform.cc +++ b/src/node_platform.cc @@ -261,6 +261,11 @@ PerIsolatePlatformData::~PerIsolatePlatformData() { Shutdown(); } +void PerIsolatePlatformData::AddShutdownCallback(void (*callback)(void*), + void* data) { + shutdown_callbacks_.emplace_back(ShutdownCallback { callback, data }); +} + void PerIsolatePlatformData::Shutdown() { if (flush_tasks_ == nullptr) return; @@ -269,21 +274,19 @@ void PerIsolatePlatformData::Shutdown() { CHECK_NULL(foreground_tasks_.Pop()); CancelPendingDelayedTasks(); + ShutdownCbList* copy = new ShutdownCbList(std::move(shutdown_callbacks_)); + flush_tasks_->data = copy; uv_close(reinterpret_cast<uv_handle_t*>(flush_tasks_), [](uv_handle_t* handle) { + std::unique_ptr<ShutdownCbList> callbacks( + static_cast<ShutdownCbList*>(handle->data)); + for (const auto& callback : *callbacks) + callback.cb(callback.data); delete reinterpret_cast<uv_async_t*>(handle); }); flush_tasks_ = nullptr; } -void PerIsolatePlatformData::ref() { - ref_count_++; -} - -int PerIsolatePlatformData::unref() { - return --ref_count_; -} - NodePlatform::NodePlatform(int thread_pool_size, TracingController* tracing_controller) { if (tracing_controller) { @@ -298,23 +301,29 @@ NodePlatform::NodePlatform(int thread_pool_size, void NodePlatform::RegisterIsolate(Isolate* isolate, uv_loop_t* loop) { Mutex::ScopedLock lock(per_isolate_mutex_); std::shared_ptr<PerIsolatePlatformData> existing = per_isolate_[isolate]; - if (existing) { - CHECK_EQ(loop, existing->event_loop()); - existing->ref(); - } else { - per_isolate_[isolate] = - std::make_shared<PerIsolatePlatformData>(isolate, loop); - } + CHECK(!existing); + per_isolate_[isolate] = + std::make_shared<PerIsolatePlatformData>(isolate, loop); } void NodePlatform::UnregisterIsolate(Isolate* isolate) { Mutex::ScopedLock lock(per_isolate_mutex_); std::shared_ptr<PerIsolatePlatformData> existing = per_isolate_[isolate]; CHECK(existing); - if (existing->unref() == 0) { - existing->Shutdown(); - per_isolate_.erase(isolate); + existing->Shutdown(); + per_isolate_.erase(isolate); +} + +void NodePlatform::AddIsolateFinishedCallback(Isolate* isolate, + void (*cb)(void*), void* data) { + Mutex::ScopedLock lock(per_isolate_mutex_); + auto it = per_isolate_.find(isolate); + if (it == per_isolate_.end()) { + CHECK(it->second); + cb(data); + return; } + it->second->AddShutdownCallback(cb, data); } void NodePlatform::Shutdown() { |