feat(napi): add back clone trait to ThreadsafeFunction

This commit is contained in:
LongYinan 2021-02-26 18:36:51 +08:00
parent e622d9693a
commit 071dcff9eb
No known key found for this signature in database
GPG key ID: A3FFE134A3E20881
2 changed files with 22 additions and 19 deletions

View file

@ -68,7 +68,7 @@ impl Into<napi_threadsafe_function_call_mode> for ThreadsafeFunctionCallMode {
/// .collect::<Result<Vec<JsNumber>>>() /// .collect::<Result<Vec<JsNumber>>>()
/// })?; /// })?;
/// ///
/// let tsfn_cloned = tsfn.try_clone()?; /// let tsfn_cloned = tsfn.clone();
/// ///
/// thread::spawn(move || { /// thread::spawn(move || {
/// let output: Vec<u32> = vec![0, 1, 2, 3]; /// let output: Vec<u32> = vec![0, 1, 2, 3];
@ -91,6 +91,24 @@ pub struct ThreadsafeFunction<T: 'static> {
_phantom: PhantomData<T>, _phantom: PhantomData<T>,
} }
impl<T: 'static> Clone for ThreadsafeFunction<T> {
fn clone(&self) -> Self {
if !self.aborted.load(Ordering::Acquire) {
let acquire_status = unsafe { sys::napi_acquire_threadsafe_function(self.raw_tsfn) };
debug_assert!(
acquire_status == sys::Status::napi_ok,
"Acquire threadsafe function failed in clone"
);
}
Self {
raw_tsfn: self.raw_tsfn,
aborted: Arc::clone(&self.aborted),
_phantom: PhantomData,
}
}
}
unsafe impl<T> Send for ThreadsafeFunction<T> {} unsafe impl<T> Send for ThreadsafeFunction<T> {}
unsafe impl<T> Sync for ThreadsafeFunction<T> {} unsafe impl<T> Sync for ThreadsafeFunction<T> {}
@ -203,21 +221,6 @@ impl<T: 'static> ThreadsafeFunction<T> {
Ok(()) Ok(())
} }
pub fn try_clone(&self) -> Result<Self> {
if self.aborted.load(Ordering::Acquire) {
return Err(Error::new(
Status::Closing,
format!("Can not clone, Thread safe function already aborted"),
));
}
check_status!(unsafe { sys::napi_acquire_threadsafe_function(self.raw_tsfn) })?;
Ok(Self {
raw_tsfn: self.raw_tsfn,
aborted: Arc::clone(&self.aborted),
_phantom: PhantomData,
})
}
/// Get the raw `ThreadSafeFunction` pointer /// Get the raw `ThreadSafeFunction` pointer
pub fn raw(&self) -> sys::napi_threadsafe_function { pub fn raw(&self) -> sys::napi_threadsafe_function {
self.raw_tsfn self.raw_tsfn

View file

@ -23,7 +23,7 @@ pub fn test_threadsafe_function(ctx: CallContext) -> Result<JsUndefined> {
.collect::<Result<Vec<JsNumber>>>() .collect::<Result<Vec<JsNumber>>>()
})?; })?;
let tsfn_cloned = tsfn.try_clone()?; let tsfn_cloned = tsfn.clone();
thread::spawn(move || { thread::spawn(move || {
let output: Vec<u32> = vec![0, 1, 2, 3]; let output: Vec<u32> = vec![0, 1, 2, 3];
@ -55,7 +55,7 @@ pub fn test_abort_threadsafe_function(ctx: CallContext) -> Result<JsBoolean> {
.collect::<Result<Vec<JsNumber>>>() .collect::<Result<Vec<JsNumber>>>()
})?; })?;
let tsfn_cloned = tsfn.try_clone()?; let tsfn_cloned = tsfn.clone();
tsfn_cloned.abort()?; tsfn_cloned.abort()?;
ctx.env.get_boolean(tsfn.aborted()) ctx.env.get_boolean(tsfn.aborted())
@ -92,7 +92,7 @@ pub fn test_call_aborted_threadsafe_function(ctx: CallContext) -> Result<JsUndef
ctx.env.create_uint32(ctx.value).map(|v| vec![v]) ctx.env.create_uint32(ctx.value).map(|v| vec![v])
})?; })?;
let tsfn_clone = tsfn.try_clone()?; let tsfn_clone = tsfn.clone();
tsfn_clone.abort()?; tsfn_clone.abort()?;
let call_status = tsfn.call(Ok(1), ThreadsafeFunctionCallMode::NonBlocking); let call_status = tsfn.call(Ok(1), ThreadsafeFunctionCallMode::NonBlocking);