From de7403f81310c76429ccfd18ee48892b356153a5 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Thu, 17 May 2018 23:46:19 +0200 Subject: [PATCH] src: cleanup per-isolate state on platform on isolate unregister Clean up once all references to an `Isolate*` are gone from the `NodePlatform`, rather than waiting for the `PerIsolatePlatformData` struct to be deleted since there may be cyclic references between that struct and the individual tasks. PR-URL: https://github.com/nodejs/node/pull/20876 Reviewed-By: Gireesh Punathil Reviewed-By: Benjamin Gruenbaum Reviewed-By: Shingo Inoue Reviewed-By: Matteo Collina Reviewed-By: Tiancheng "Timothy" Gu Reviewed-By: John-David Dalton Reviewed-By: Gus Caplan --- src/node_platform.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/node_platform.cc b/src/node_platform.cc index 2885c72ed71213..6fc83950d3083e 100644 --- a/src/node_platform.cc +++ b/src/node_platform.cc @@ -82,12 +82,14 @@ void PerIsolatePlatformData::PostIdleTask(std::unique_ptr task) { } void PerIsolatePlatformData::PostTask(std::unique_ptr task) { + CHECK_NE(flush_tasks_, nullptr); foreground_tasks_.Push(std::move(task)); uv_async_send(flush_tasks_); } void PerIsolatePlatformData::PostDelayedTask( std::unique_ptr task, double delay_in_seconds) { + CHECK_NE(flush_tasks_, nullptr); std::unique_ptr delayed(new DelayedTask()); delayed->task = std::move(task); delayed->platform_data = shared_from_this(); @@ -97,6 +99,13 @@ void PerIsolatePlatformData::PostDelayedTask( } PerIsolatePlatformData::~PerIsolatePlatformData() { + Shutdown(); +} + +void PerIsolatePlatformData::Shutdown() { + if (flush_tasks_ == nullptr) + return; + while (FlushForegroundTasksInternal()) {} CancelPendingDelayedTasks(); @@ -104,6 +113,7 @@ PerIsolatePlatformData::~PerIsolatePlatformData() { [](uv_handle_t* handle) { delete reinterpret_cast(handle); }); + flush_tasks_ = nullptr; } void PerIsolatePlatformData::ref() { @@ -144,6 +154,7 @@ void NodePlatform::UnregisterIsolate(IsolateData* isolate_data) { std::shared_ptr existing = per_isolate_[isolate]; CHECK(existing); if (existing->unref() == 0) { + existing->Shutdown(); per_isolate_.erase(isolate); } }