Skip to content

Commit

Permalink
node-api: stop ref gc during environment teardown
Browse files Browse the repository at this point in the history
A gc may happen during environment teardown. Thus, during finalization
initiated by environment teardown we must remove the V8 finalizer
before calling the Node-API finalizer.

Fixes: nodejs#37236
PR-URL: nodejs#37616
  • Loading branch information
gabrielschulhof committed Mar 6, 2021
1 parent 26fed3f commit 8eb03c4
Showing 1 changed file with 13 additions and 1 deletion.
14 changes: 13 additions & 1 deletion src/js_native_api_v8.cc
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,10 @@ class RefBase : protected Finalizer, RefTracker {
if (is_env_teardown && RefCount() > 0) _refcount = 0;

if (_finalize_callback != nullptr) {
_env->CallFinalizer(_finalize_callback, _finalize_data, _finalize_hint);
// This ensures that we never call the finalizer twice.
napi_finalize fini = _finalize_callback;
_finalize_callback = nullptr;
_env->CallFinalizer(fini, _finalize_data, _finalize_hint);
}

// this is safe because if a request to delete the reference
Expand Down Expand Up @@ -355,6 +356,17 @@ class Reference : public RefBase {
}
}

protected:
inline void Finalize(bool is_env_teardown = false) override {
// During env teardown, `~napi_env()` alone is responsible for finalizing.
// Thus, we don't want any stray gc passes to trigger a second call to
// `Finalize()`, so let's reset the persistent here.
if (is_env_teardown) _persistent.ClearWeak();

// Chain up to perform the rest of the finalization.
RefBase::Finalize(is_env_teardown);
}

private:
// The N-API finalizer callback may make calls into the engine. V8's heap is
// not in a consistent state during the weak callback, and therefore it does
Expand Down

0 comments on commit 8eb03c4

Please sign in to comment.