commit
673fa3b7bd
4 changed files with 53 additions and 20 deletions
|
@ -673,6 +673,32 @@ impl Env {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn unwrap_from_ref<T: 'static>(&self, js_ref: &Ref<()>) -> Result<&'static mut T> {
|
||||
unsafe {
|
||||
let mut unknown_tagged_object: *mut c_void = ptr::null_mut();
|
||||
check_status!(sys::napi_unwrap(
|
||||
self.0,
|
||||
js_ref.raw_value,
|
||||
&mut unknown_tagged_object,
|
||||
))?;
|
||||
|
||||
let type_id = unknown_tagged_object as *const TypeId;
|
||||
if *type_id == TypeId::of::<T>() {
|
||||
let tagged_object = unknown_tagged_object as *mut TaggedObject<T>;
|
||||
(*tagged_object).object.as_mut().ok_or(Error {
|
||||
status: Status::InvalidArg,
|
||||
reason: "Invalid argument, nothing attach to js_object".to_owned(),
|
||||
})
|
||||
} else {
|
||||
Err(Error {
|
||||
status: Status::InvalidArg,
|
||||
reason: "Invalid argument, T on unrwap is not the type of wrapped object".to_owned(),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn drop_wrapped<T: 'static>(&self, js_object: JsObject) -> Result<()> {
|
||||
unsafe {
|
||||
|
@ -706,13 +732,15 @@ impl Env {
|
|||
{
|
||||
let mut raw_ref = ptr::null_mut();
|
||||
let initial_ref_count = 1;
|
||||
let raw_value = unsafe { value.raw() };
|
||||
check_status!(unsafe {
|
||||
sys::napi_create_reference(self.0, value.raw(), initial_ref_count, &mut raw_ref)
|
||||
sys::napi_create_reference(self.0, raw_value, initial_ref_count, &mut raw_ref)
|
||||
})?;
|
||||
Ok(Ref {
|
||||
raw_ref,
|
||||
count: 1,
|
||||
inner: (),
|
||||
raw_value,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ pub struct Ref<T> {
|
|||
pub(crate) raw_ref: sys::napi_ref,
|
||||
pub(crate) count: u32,
|
||||
pub(crate) inner: T,
|
||||
pub(crate) raw_value: sys::napi_value,
|
||||
}
|
||||
|
||||
unsafe impl<T> Send for Ref<T> {}
|
||||
|
@ -30,6 +31,7 @@ impl<T> Ref<T> {
|
|||
raw_ref,
|
||||
count: ref_count,
|
||||
inner,
|
||||
raw_value: js_value.value,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ impl Into<napi_threadsafe_function_call_mode> for ThreadsafeFunctionCallMode {
|
|||
/// .collect::<Result<Vec<JsNumber>>>()
|
||||
/// })?;
|
||||
///
|
||||
/// let tsfn_cloned = tsfn.try_clone()?;
|
||||
/// let tsfn_cloned = tsfn.clone();
|
||||
///
|
||||
/// thread::spawn(move || {
|
||||
/// let output: Vec<u32> = vec![0, 1, 2, 3];
|
||||
|
@ -91,6 +91,24 @@ pub struct ThreadsafeFunction<T: 'static> {
|
|||
_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> Sync for ThreadsafeFunction<T> {}
|
||||
|
||||
|
@ -203,21 +221,6 @@ impl<T: 'static> ThreadsafeFunction<T> {
|
|||
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
|
||||
pub fn raw(&self) -> sys::napi_threadsafe_function {
|
||||
self.raw_tsfn
|
||||
|
|
|
@ -23,7 +23,7 @@ pub fn test_threadsafe_function(ctx: CallContext) -> Result<JsUndefined> {
|
|||
.collect::<Result<Vec<JsNumber>>>()
|
||||
})?;
|
||||
|
||||
let tsfn_cloned = tsfn.try_clone()?;
|
||||
let tsfn_cloned = tsfn.clone();
|
||||
|
||||
thread::spawn(move || {
|
||||
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>>>()
|
||||
})?;
|
||||
|
||||
let tsfn_cloned = tsfn.try_clone()?;
|
||||
let tsfn_cloned = tsfn.clone();
|
||||
|
||||
tsfn_cloned.abort()?;
|
||||
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])
|
||||
})?;
|
||||
|
||||
let tsfn_clone = tsfn.try_clone()?;
|
||||
let tsfn_clone = tsfn.clone();
|
||||
tsfn_clone.abort()?;
|
||||
|
||||
let call_status = tsfn.call(Ok(1), ThreadsafeFunctionCallMode::NonBlocking);
|
||||
|
|
Loading…
Reference in a new issue