diff --git a/crates/napi/src/threadsafe_function.rs b/crates/napi/src/threadsafe_function.rs index 8ce36e20..4912d6e6 100644 --- a/crates/napi/src/threadsafe_function.rs +++ b/crates/napi/src/threadsafe_function.rs @@ -214,9 +214,9 @@ impl ThreadsafeFunction { async_resource_name, max_queue_size, initial_thread_count, - ptr, - Some(thread_finalize_cb::), aborted_ptr as *mut c_void, + Some(thread_finalize_cb::), + ptr, Some(call_js_cb::), &mut raw_tsfn, ) @@ -355,8 +355,8 @@ unsafe extern "C" fn thread_finalize_cb( R: 'static + Send + FnMut(ThreadSafeCallContext) -> Result>, { // cleanup - drop(unsafe { Box::::from_raw(finalize_data.cast()) }); - let aborted = unsafe { Arc::>::from_raw(finalize_hint.cast()) }; + drop(unsafe { Box::::from_raw(finalize_hint.cast()) }); + let aborted = unsafe { Arc::>::from_raw(finalize_data.cast()) }; let mut is_aborted = aborted.lock().unwrap(); *is_aborted = true; } diff --git a/examples/napi/__test__/typegen.spec.ts.md b/examples/napi/__test__/typegen.spec.ts.md index a05091fd..bcf1735e 100644 --- a/examples/napi/__test__/typegen.spec.ts.md +++ b/examples/napi/__test__/typegen.spec.ts.md @@ -193,6 +193,7 @@ Generated by [AVA](https://avajs.dev). export function threadsafeFunctionThrowError(cb: (...args: any[]) => any): void␊ export function threadsafeFunctionFatalMode(cb: (...args: any[]) => any): void␊ export function threadsafeFunctionFatalModeError(cb: (...args: any[]) => any): void␊ + export function threadsafeFunctionClosureCapture(func: (...args: any[]) => any): void␊ export function useTokioWithoutAsync(): void␊ export function getBuffer(): Buffer␊ export function appendBuffer(buf: Buffer): Buffer␊ diff --git a/examples/napi/__test__/typegen.spec.ts.snap b/examples/napi/__test__/typegen.spec.ts.snap index 69867ce3..6091812b 100644 Binary files a/examples/napi/__test__/typegen.spec.ts.snap and b/examples/napi/__test__/typegen.spec.ts.snap differ diff --git a/examples/napi/__test__/values.spec.ts b/examples/napi/__test__/values.spec.ts index 39fcd131..bf351b0b 100644 --- a/examples/napi/__test__/values.spec.ts +++ b/examples/napi/__test__/values.spec.ts @@ -50,6 +50,7 @@ import { bigintGetU64AsString, callThreadsafeFunction, threadsafeFunctionThrowError, + threadsafeFunctionClosureCapture, asyncPlus100, getGlobal, getUndefined, @@ -691,6 +692,15 @@ Napi4Test('throw error from thread safe function', async (t) => { t.is(err!.message, 'ThrowFromNative') }) +Napi4Test('thread safe function closure capture data', (t) => { + return new Promise((resolve) => { + threadsafeFunctionClosureCapture(() => { + resolve() + t.pass() + }) + }) +}) + Napi4Test('resolve value from thread safe function fatal mode', async (t) => { const tsfnFatalMode = new Promise((resolve) => { threadsafeFunctionFatalMode(resolve) diff --git a/examples/napi/index.d.ts b/examples/napi/index.d.ts index 30690e82..e7c74e2b 100644 --- a/examples/napi/index.d.ts +++ b/examples/napi/index.d.ts @@ -183,6 +183,7 @@ export function callThreadsafeFunction(callback: (...args: any[]) => any): void export function threadsafeFunctionThrowError(cb: (...args: any[]) => any): void export function threadsafeFunctionFatalMode(cb: (...args: any[]) => any): void export function threadsafeFunctionFatalModeError(cb: (...args: any[]) => any): void +export function threadsafeFunctionClosureCapture(func: (...args: any[]) => any): void export function useTokioWithoutAsync(): void export function getBuffer(): Buffer export function appendBuffer(buf: Buffer): Buffer diff --git a/examples/napi/src/threadsafe_function.rs b/examples/napi/src/threadsafe_function.rs index f0cc24c3..089fa858 100644 --- a/examples/napi/src/threadsafe_function.rs +++ b/examples/napi/src/threadsafe_function.rs @@ -3,7 +3,7 @@ use std::thread; use napi::{ bindgen_prelude::*, threadsafe_function::{ErrorStrategy, ThreadsafeFunction, ThreadsafeFunctionCallMode}, - JsBoolean, + JsBoolean, JsString, }; #[napi] @@ -61,3 +61,18 @@ pub fn threadsafe_function_fatal_mode_error(cb: JsFunction) -> Result<()> { }); Ok(()) } + +#[napi] +fn threadsafe_function_closure_capture(func: JsFunction) -> napi::Result<()> { + let str = "test"; + let tsfn: ThreadsafeFunction<()> = func + .create_threadsafe_function(0, move |_| { + println!("{}", str); // str is NULL at this point + Ok(Vec::::new()) + }) + .unwrap(); + + tsfn.call(Ok(()), ThreadsafeFunctionCallMode::NonBlocking); + + Ok(()) +}