From d1a5f84aa0064dc3a237efdcf1fc5269d59d7f52 Mon Sep 17 00:00:00 2001 From: LongYinan Date: Sun, 21 Nov 2021 14:49:04 +0800 Subject: [PATCH] fix(napi): allow ErrorStrategy to be specified while creating TSFN --- crates/napi/src/js_values/function.rs | 5 ++-- examples/napi/__test__/typegen.spec.ts.md | 1 + examples/napi/__test__/typegen.spec.ts.snap | Bin 1115 -> 1129 bytes examples/napi/__test__/values.spec.ts | 8 +++++++ examples/napi/index.d.ts | 1 + examples/napi/src/threadsafe_function.rs | 24 ++++++++++++++------ 6 files changed, 30 insertions(+), 9 deletions(-) diff --git a/crates/napi/src/js_values/function.rs b/crates/napi/src/js_values/function.rs index 360b8d36..e0ba67d8 100644 --- a/crates/napi/src/js_values/function.rs +++ b/crates/napi/src/js_values/function.rs @@ -120,15 +120,16 @@ impl JsFunction { } #[cfg(feature = "napi4")] - pub fn create_threadsafe_function( + pub fn create_threadsafe_function( &self, max_queue_size: usize, callback: F, - ) -> Result> + ) -> Result> where T: 'static, V: NapiRaw, F: 'static + Send + FnMut(ThreadSafeCallContext) -> Result>, + ES: crate::threadsafe_function::ErrorStrategy::T, { ThreadsafeFunction::create(self.0.env, self.0.value, max_queue_size, callback) } diff --git a/examples/napi/__test__/typegen.spec.ts.md b/examples/napi/__test__/typegen.spec.ts.md index 937c2973..d46afc27 100644 --- a/examples/napi/__test__/typegen.spec.ts.md +++ b/examples/napi/__test__/typegen.spec.ts.md @@ -57,6 +57,7 @@ Generated by [AVA](https://avajs.dev). export function withAbortController(a: number, b: number, signal: AbortSignal): Promise␊ 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 getBuffer(): Buffer␊ export class Animal {␊ readonly kind: Kind␊ diff --git a/examples/napi/__test__/typegen.spec.ts.snap b/examples/napi/__test__/typegen.spec.ts.snap index f58e243cfbf800004144eee0f5368207b262b8a3..717c6738755ba4449f161e5187b7e83e372fb051 100644 GIT binary patch literal 1129 zcmV-v1eW_jRzV;O&2QM- z9(!$nL~lib-h1v}=&|PxDL-UOS{sY{Adkpzz8MbZA<}3xb{db~efHO%|9tn`FQ0$$ z@85s?{_9S|{(gSaXgq3s;^du=8=rpk_6gigr7|RvLK|{+-fdsM9Q@e1><aBc#nIt=kQm?2ZR|yq^N>d4fY^hy7EvJ2j>(N=F%sCn z+5nab&Xtmi{6ta_!;lGxeS#Z%Cv)oJ7Rn;!e4{mBW(2D5^e z+@wmJJF2q9U}4mTP?33*GW z1$-qhn25zYP|mT%t*;w zms?(4mQ3jMa%v^-hVqkO8M0Eoy=Sjn?Rl-{3a(Z+CEAdMQqU-3p4bfLOdGt&7m#UB zhHnCb4~Wdh{+L%fYT9t*I#o6PHJ2gf7Gtt0$RSDGLKXCS9*NojyPnJ)+jHHk43=$; zS3K2wt(G?}wZn=Axh#__>>@OQ=Nfrzxd=Lec>&n!0j1GIVI_tspwA*=pz*rDg$PH> zEMVAlM0Q+tzgF+&?1NOxnQYr&!EYOx!fRCk3)?+BAkLn}`-<+OCzWqr3PYLDp2kXy z79sM9!9EM7Fvw=DqKYA+2HUBp3+Q@t2);JMy`$~nFR5W-ZyUS@)6XWMwT*I?O2qws&=>rzAcD;dLw&|$LX zpIGiQ#YuBa#HrS#E!c!|*9@#-DR@T4INJg@;c(S`d8#xrc%J2kztTFIh|>o1F>?23 z0R^n>v(5^l&>yGiH49Bf&llG@Z%2|&*eW(RgFHBTouTH;)rZxCopL&c{nKx###!&q zx8@{d-WalA1`P4N8LVp6P$DwtTido73wOrtO=uQE4 zR?Uv%L=eufLP)EzyAE`XaD^5 z`)|J-)y!}3tX6wc`^d^iAJ#tp;LB%lKNnJyKyal=r`v1Yz8U?{9t=kw;YsX+e7Z!8 z6CP+LIGKQcD`cpgx<^`4()78~lJUt!8M2?mIbgk|2 z+9m!C8l>cmXl5j?Pfr~1wvAWco}Nmvu({<_ zWl2ougSnBMI~rYjn~)Xq?LB+NYR_slQ?RwVFVV)#7n}wGbNGI6#FWO1d=05`g#XSX z_<%s~?T=ZdqoxT*rc+kqFC*d8$Y69j2QelSyHEzbT}7fYz_uqxmhF}5mj=tU#+xWn z%|^qS7usP-gWQzK4R#SafmaH7Ou29x!>RyG^?+1pBDWI49MESTFi?2i-#~z)Wf?GR zIy}87yI-Ss*ZE(n#Y{GBFz2_4OzyQTfVu5H9uQ~G`h81x-IIzpFSw?RD@S1^2I~;H zL}Q-?of~A!R#Ct=>Q8{$AIRxM8ar69e_#3JjZythIpoeMfi|Cr0WL8#2wEeG6 z?JWH>O%wGDUw|#Jn~FrYd|Yi~+@y#i?EV$?yl;3LwnL~~qS%B}JcdON?aKlDW|o>x zOG8D+&|5C&N9^(OFPKb|ONiJ;|3xIVJ=3=w! hjd{LBnjSUeX<38L8S59~?-eM}#J|mz$R%$K005wMA;16t diff --git a/examples/napi/__test__/values.spec.ts b/examples/napi/__test__/values.spec.ts index 6dbf8e47..01a9e92b 100644 --- a/examples/napi/__test__/values.spec.ts +++ b/examples/napi/__test__/values.spec.ts @@ -47,6 +47,7 @@ import { getNull, setSymbolInObj, createSymbol, + threadsafeFunctionFatalMode, } from '../' test('export const', (t) => { @@ -304,6 +305,13 @@ Napi4Test('throw error from thread safe function', async (t) => { t.is(err.message, 'ThrowFromNative') }) +Napi4Test('throw error from thread safe function fatal mode', async (t) => { + const tsfnFatalMode = new Promise((resolve) => { + threadsafeFunctionFatalMode(resolve) + }) + t.true(await tsfnFatalMode) +}) + Napi4Test('await Promise in rust', async (t) => { const fx = 20 const result = await asyncPlus100( diff --git a/examples/napi/index.d.ts b/examples/napi/index.d.ts index 396941f4..d5476cc4 100644 --- a/examples/napi/index.d.ts +++ b/examples/napi/index.d.ts @@ -47,6 +47,7 @@ export function withoutAbortController(a: number, b: number): Promise export function withAbortController(a: number, b: number, signal: AbortSignal): Promise 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 getBuffer(): Buffer export class Animal { readonly kind: Kind diff --git a/examples/napi/src/threadsafe_function.rs b/examples/napi/src/threadsafe_function.rs index 2115fd43..9a238b88 100644 --- a/examples/napi/src/threadsafe_function.rs +++ b/examples/napi/src/threadsafe_function.rs @@ -2,14 +2,15 @@ use std::thread; use napi::{ bindgen_prelude::*, - threadsafe_function::{ThreadSafeCallContext, ThreadsafeFunctionCallMode}, + threadsafe_function::{ErrorStrategy, ThreadsafeFunction, ThreadsafeFunctionCallMode}, }; #[napi] pub fn call_threadsafe_function(callback: JsFunction) -> Result<()> { - let tsfn = callback.create_threadsafe_function(0, |ctx: ThreadSafeCallContext| { - ctx.env.create_uint32(ctx.value + 1).map(|v| vec![v]) - })?; + let tsfn: ThreadsafeFunction = callback + .create_threadsafe_function(0, |ctx| { + ctx.env.create_uint32(ctx.value + 1).map(|v| vec![v]) + })?; for n in 0..100 { let tsfn = tsfn.clone(); thread::spawn(move || { @@ -21,9 +22,8 @@ pub fn call_threadsafe_function(callback: JsFunction) -> Result<()> { #[napi] pub fn threadsafe_function_throw_error(cb: JsFunction) -> Result<()> { - let tsfn = cb.create_threadsafe_function(0, |ctx: ThreadSafeCallContext| { - ctx.env.get_boolean(ctx.value).map(|v| vec![v]) - })?; + let tsfn: ThreadsafeFunction = + cb.create_threadsafe_function(0, |ctx| ctx.env.get_boolean(ctx.value).map(|v| vec![v]))?; thread::spawn(move || { tsfn.call( Err(Error::new( @@ -35,3 +35,13 @@ pub fn threadsafe_function_throw_error(cb: JsFunction) -> Result<()> { }); Ok(()) } + +#[napi] +pub fn threadsafe_function_fatal_mode(cb: JsFunction) -> Result<()> { + let tsfn: ThreadsafeFunction = + cb.create_threadsafe_function(0, |ctx| ctx.env.get_boolean(ctx.value).map(|v| vec![v]))?; + thread::spawn(move || { + tsfn.call(true, ThreadsafeFunctionCallMode::Blocking); + }); + Ok(()) +}