summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
authorNathan Whitaker <17734409+nathanwhit@users.noreply.github.com>2024-08-28 13:42:42 -0700
committerGitHub <noreply@github.com>2024-08-28 13:42:42 -0700
commit37501aa32357e75b9ddc92198da94d92fcdd0798 (patch)
treef87a09bbe351ebe29b0c1b4fff4dca5b4f066ced /cli
parent6ccaebcdeae95a82b270ac5bde78b65b37fadb45 (diff)
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.
Diffstat (limited to 'cli')
-rw-r--r--cli/napi/js_native_api.rs23
1 files changed, 17 insertions, 6 deletions
diff --git a/cli/napi/js_native_api.rs b/cli/napi/js_native_api.rs
index 5269d8d1d..e922d8c3f 100644
--- a/cli/napi/js_native_api.rs
+++ b/cli/napi/js_native_api.rs
@@ -3307,19 +3307,30 @@ fn napi_resolve_deferred(
check_arg!(env, result);
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 =
unsafe { NonNull::new_unchecked(deferred as *mut v8::PromiseResolver) };
let global = unsafe { v8::Global::from_raw(env.isolate(), deferred_ptr) };
let resolver = v8::Local::new(&mut env.scope(), global);
- if !resolver
+ let success = resolver
.resolve(&mut env.scope(), result.unwrap())
- .unwrap_or(false)
- {
- return napi_generic_failure;
- }
+ .unwrap_or(false);
- napi_ok
+ // Restore policy
+ env
+ .scope()
+ .set_microtasks_policy(v8::MicrotasksPolicy::Auto);
+
+ if success {
+ napi_ok
+ } else {
+ napi_generic_failure
+ }
}
#[napi_sym]