fix: add MicrotasksScope for worker exit emit in ContextWillDestroy (#51326)

a39108c5a4 (#47244) replaced gin_helper::EmitEvent with a direct
`v8::Function::Call()` in `WebWorkerObserver::ContextWillDestroy`
to avoid re-entering the microtask checkpoint during worker teardown.

V8 `DCHECK()`s that a policy is set. Under the old code path, this
happened with a node::CallbackScope. Under the new code path, it's
possible for a policy to not be set, causing that `DCHECK()` to fail.

This PR copies a39108c5a4's changes in `ShareEnvironmentWithContext()`:
it explicitly adds a `kDoNotRunMicrotasks` scope.
This commit is contained in:
Charles Kerr
2026-04-27 15:18:09 -05:00
committed by GitHub
parent 002249c0ed
commit 6c49cb3b27

View File

@@ -252,6 +252,13 @@ void WebWorkerObserver::ContextWillDestroy(v8::Local<v8::Context> context) {
.ToLocal(&emit_v) &&
emit_v->IsFunction()) {
v8::Local<v8::Value> args[] = {gin::StringToV8(isolate, "exit")};
// Worker/worklet contexts use kScoped microtask policy (set by
// Blink). V8 DCHECKs that a MicrotasksScope exists around every
// Call() under that policy. We use kDoNotRunMicrotasks because
// the context is mid-teardown.
v8::MicrotasksScope microtasks_scope{
isolate, ctx->GetMicrotaskQueue(),
v8::MicrotasksScope::kDoNotRunMicrotasks};
v8::TryCatch try_catch(isolate);
emit_v.As<v8::Function>()
->Call(ctx, env->process_object(), 1, args)