diff options
author | Matt Mastracci <matthew@mastracci.com> | 2023-12-11 10:52:55 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-11 10:52:55 -0700 |
commit | d13e45f2b3e50b85953c31d9c16e35d0cd87545f (patch) | |
tree | 1b206fa8dafc4ee23cebfd586a58a192b3557d66 /cli/napi/async.rs | |
parent | a272bc1bd0793b2f522e4e611963231dc344531f (diff) |
perf(ext/napi): port NAPI to v8 tasks (#21406)
Part 2 of removing middleware.
This is somewhat awkward because `V8CrossThreadTaskSpawner` requires
tasks to be `Send`, but NAPI makes heavy use of `!Send` pointers. In
addition, Rust causes a closure to be `!Send` if you pull a `!Send`
value out of a struct.
---------
Signed-off-by: Matt Mastracci <matthew@mastracci.com>
Co-authored-by: Divy Srivastava <dj.srivastava23@gmail.com>
Diffstat (limited to 'cli/napi/async.rs')
-rw-r--r-- | cli/napi/async.rs | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/cli/napi/async.rs b/cli/napi/async.rs index 48de36728..1fb0c6374 100644 --- a/cli/napi/async.rs +++ b/cli/napi/async.rs @@ -11,6 +11,9 @@ pub struct AsyncWork { pub complete: napi_async_complete_callback, } +unsafe impl Send for AsyncWork {} +unsafe impl Sync for AsyncWork {} + #[napi_sym::napi_sym] fn napi_create_async_work( _env: *mut Env, @@ -61,12 +64,22 @@ fn napi_queue_async_work( return napi_invalid_arg; }; - let fut = Box::new(move || { - (work.execute)(env_ptr as napi_env, work.data); - // Note: Must be called from the loop thread. - (work.complete)(env_ptr as napi_env, napi_ok, work.data); - }); - env.add_async_work(fut); + #[repr(transparent)] + struct SendPtr<T>(*const T); + unsafe impl<T> Send for SendPtr<T> {} + unsafe impl<T> Sync for SendPtr<T> {} + let send_env = SendPtr(env_ptr); + + #[inline(always)] + fn do_work(ptr: SendPtr<Env>, work: &AsyncWork) { + // SAFETY: This is a valid async work queue call and it runs on the event loop thread + unsafe { + (work.execute)(ptr.0 as napi_env, work.data); + (work.complete)(ptr.0 as napi_env, napi_ok, work.data); + } + } + + env.add_async_work(move || do_work(send_env, work)); napi_ok } |