1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-21 15:04:11 -05:00

fix(napi): Don't run microtasks in napi_resolve_deferred (#25246)

Fixes an incredibly obscure bug that causes parcel's file watcher to not
get any file update notifications on macOS.

The issue was that the native addon was calling `napi_resolve_deferred`,
but when we resolved the promise, v8 was running microtasks
automatically. That executed JS, which called back into the native addon
and broke the addon's assumption that the call wouldn't be reentrant.
This commit is contained in:
Nathan Whitaker 2024-08-28 13:42:42 -07:00 committed by GitHub
parent 6ccaebcdea
commit 37501aa323
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -3307,19 +3307,30 @@ fn napi_resolve_deferred(
check_arg!(env, result); check_arg!(env, result);
check_arg!(env, deferred); check_arg!(env, deferred);
// Make sure microtasks don't run and call back into JS
env
.scope()
.set_microtasks_policy(v8::MicrotasksPolicy::Explicit);
let deferred_ptr = let deferred_ptr =
unsafe { NonNull::new_unchecked(deferred as *mut v8::PromiseResolver) }; unsafe { NonNull::new_unchecked(deferred as *mut v8::PromiseResolver) };
let global = unsafe { v8::Global::from_raw(env.isolate(), deferred_ptr) }; let global = unsafe { v8::Global::from_raw(env.isolate(), deferred_ptr) };
let resolver = v8::Local::new(&mut env.scope(), global); let resolver = v8::Local::new(&mut env.scope(), global);
if !resolver let success = resolver
.resolve(&mut env.scope(), result.unwrap()) .resolve(&mut env.scope(), result.unwrap())
.unwrap_or(false) .unwrap_or(false);
{
return napi_generic_failure;
}
napi_ok // Restore policy
env
.scope()
.set_microtasks_policy(v8::MicrotasksPolicy::Auto);
if success {
napi_ok
} else {
napi_generic_failure
}
} }
#[napi_sym] #[napi_sym]