diff --git a/src/node.h b/src/node.h index f3da4574019254..50f85ae338914e 100644 --- a/src/node.h +++ b/src/node.h @@ -298,6 +298,7 @@ class NODE_EXTERN MultiIsolatePlatform : public v8::Platform { // This function may only be called once per `Isolate`, and discard any // pending delayed tasks scheduled for that isolate. + // This needs to be called right before calling `Isolate::Dispose()`. virtual void UnregisterIsolate(v8::Isolate* isolate) = 0; // The platform should call the passed function once all state associated diff --git a/src/node_main_instance.cc b/src/node_main_instance.cc index eea847725300f0..86a857299f6e90 100644 --- a/src/node_main_instance.cc +++ b/src/node_main_instance.cc @@ -99,8 +99,8 @@ NodeMainInstance::~NodeMainInstance() { if (!owns_isolate_) { return; } - isolate_->Dispose(); platform_->UnregisterIsolate(isolate_); + isolate_->Dispose(); } int NodeMainInstance::Run() { diff --git a/src/node_worker.cc b/src/node_worker.cc index a7449e44118a59..2f43780a951ad4 100644 --- a/src/node_worker.cc +++ b/src/node_worker.cc @@ -190,8 +190,13 @@ class WorkerThreadData { *static_cast(data) = true; }, &platform_finished); - isolate->Dispose(); + // The order of these calls is important; if the Isolate is first disposed + // and then unregistered, there is a race condition window in which no + // new Isolate at the same address can successfully be registered with + // the platform. + // (Refs: https://github.com/nodejs/node/issues/30846) w_->platform_->UnregisterIsolate(isolate); + isolate->Dispose(); // Wait until the platform has cleaned up all relevant resources. while (!platform_finished) diff --git a/test/cctest/node_test_fixture.h b/test/cctest/node_test_fixture.h index c8cb9232978821..44f4466356e1b7 100644 --- a/test/cctest/node_test_fixture.h +++ b/test/cctest/node_test_fixture.h @@ -116,8 +116,8 @@ class NodeTestFixture : public NodeZeroIsolateTestFixture { void TearDown() override { platform->DrainTasks(isolate_); isolate_->Exit(); - isolate_->Dispose(); platform->UnregisterIsolate(isolate_); + isolate_->Dispose(); isolate_ = nullptr; NodeZeroIsolateTestFixture::TearDown(); } diff --git a/test/cctest/test_platform.cc b/test/cctest/test_platform.cc index 73057bb2d8c03a..c56766b5ec8611 100644 --- a/test/cctest/test_platform.cc +++ b/test/cctest/test_platform.cc @@ -101,6 +101,6 @@ TEST_F(NodeZeroIsolateTestFixture, IsolatePlatformDelegateTest) { // Graceful shutdown delegate->Shutdown(); - isolate->Dispose(); platform->UnregisterIsolate(isolate); + isolate->Dispose(); }