Skip to content

Commit 8eb03c4

Browse files
node-api: stop ref gc during environment teardown
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: #37236 PR-URL: #37616
1 parent 26fed3f commit 8eb03c4

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

src/js_native_api_v8.cc

+13-1
Original file line numberDiff line numberDiff line change
@@ -278,9 +278,10 @@ class RefBase : protected Finalizer, RefTracker {
278278
if (is_env_teardown && RefCount() > 0) _refcount = 0;
279279

280280
if (_finalize_callback != nullptr) {
281-
_env->CallFinalizer(_finalize_callback, _finalize_data, _finalize_hint);
282281
// This ensures that we never call the finalizer twice.
282+
napi_finalize fini = _finalize_callback;
283283
_finalize_callback = nullptr;
284+
_env->CallFinalizer(fini, _finalize_data, _finalize_hint);
284285
}
285286

286287
// this is safe because if a request to delete the reference
@@ -355,6 +356,17 @@ class Reference : public RefBase {
355356
}
356357
}
357358

359+
protected:
360+
inline void Finalize(bool is_env_teardown = false) override {
361+
// During env teardown, `~napi_env()` alone is responsible for finalizing.
362+
// Thus, we don't want any stray gc passes to trigger a second call to
363+
// `Finalize()`, so let's reset the persistent here.
364+
if (is_env_teardown) _persistent.ClearWeak();
365+
366+
// Chain up to perform the rest of the finalization.
367+
RefBase::Finalize(is_env_teardown);
368+
}
369+
358370
private:
359371
// The N-API finalizer callback may make calls into the engine. V8's heap is
360372
// not in a consistent state during the weak callback, and therefore it does

0 commit comments

Comments
 (0)