src: unregister Isolate with platform before disposing

I previously thought the order of these calls was no longer
relevant. I was wrong.

This commit undoes the changes from 312c02d25e, adds a comment
explaining why I was wrong, and flips the order of the calls
elsewhere for consistency, the latter having been the goal
of 312c02d25e.

Fixes: https://github.com/nodejs/node/issues/30846
Refs: https://github.com/nodejs/node/pull/30181

PR-URL: https://github.com/nodejs/node/pull/30909
Reviewed-By: Shelley Vohr <codebytere@gmail.com>
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: David Carlier <devnexen@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
This commit is contained in:
Anna Henningsen 2019-12-11 21:48:47 -05:00 committed by Rich Trott
parent f8018f289e
commit 25447d82d3
5 changed files with 10 additions and 4 deletions

View File

@ -298,6 +298,7 @@ class NODE_EXTERN MultiIsolatePlatform : public v8::Platform {
// This function may only be called once per `Isolate`, and discard any // This function may only be called once per `Isolate`, and discard any
// pending delayed tasks scheduled for that isolate. // pending delayed tasks scheduled for that isolate.
// This needs to be called right before calling `Isolate::Dispose()`.
virtual void UnregisterIsolate(v8::Isolate* isolate) = 0; virtual void UnregisterIsolate(v8::Isolate* isolate) = 0;
// The platform should call the passed function once all state associated // The platform should call the passed function once all state associated

View File

@ -99,8 +99,8 @@ NodeMainInstance::~NodeMainInstance() {
if (!owns_isolate_) { if (!owns_isolate_) {
return; return;
} }
isolate_->Dispose();
platform_->UnregisterIsolate(isolate_); platform_->UnregisterIsolate(isolate_);
isolate_->Dispose();
} }
int NodeMainInstance::Run() { int NodeMainInstance::Run() {

View File

@ -190,8 +190,13 @@ class WorkerThreadData {
*static_cast<bool*>(data) = true; *static_cast<bool*>(data) = true;
}, &platform_finished); }, &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); w_->platform_->UnregisterIsolate(isolate);
isolate->Dispose();
// Wait until the platform has cleaned up all relevant resources. // Wait until the platform has cleaned up all relevant resources.
while (!platform_finished) while (!platform_finished)

View File

@ -116,8 +116,8 @@ class NodeTestFixture : public NodeZeroIsolateTestFixture {
void TearDown() override { void TearDown() override {
platform->DrainTasks(isolate_); platform->DrainTasks(isolate_);
isolate_->Exit(); isolate_->Exit();
isolate_->Dispose();
platform->UnregisterIsolate(isolate_); platform->UnregisterIsolate(isolate_);
isolate_->Dispose();
isolate_ = nullptr; isolate_ = nullptr;
NodeZeroIsolateTestFixture::TearDown(); NodeZeroIsolateTestFixture::TearDown();
} }

View File

@ -101,6 +101,6 @@ TEST_F(NodeZeroIsolateTestFixture, IsolatePlatformDelegateTest) {
// Graceful shutdown // Graceful shutdown
delegate->Shutdown(); delegate->Shutdown();
isolate->Dispose();
platform->UnregisterIsolate(isolate); platform->UnregisterIsolate(isolate);
isolate->Dispose();
} }