1use std::ptr;
2
3use tracing::debug;
4
5use crate::sys::napi_threadsafe_function;
6use crate::NjError;
7use crate::val::JsEnv;
8use crate::sys::napi_env;
9
10pub struct ThreadSafeFunction {
12 env: JsEnv,
13 tf: napi_threadsafe_function,
14}
15
16unsafe impl Sync for ThreadSafeFunction {}
17unsafe impl Send for ThreadSafeFunction {}
18
19impl ThreadSafeFunction {
20 pub fn new<E>(env: E, tf: napi_threadsafe_function) -> Self
21 where
22 E: Into<JsEnv>,
23 {
24 Self {
25 env: env.into(),
26 tf,
27 }
28 }
29
30 pub fn inner(self) -> napi_threadsafe_function {
31 self.tf
32 }
33
34 pub fn env(&self) -> napi_env {
35 self.env.inner()
36 }
37
38 pub fn call(&self, data: Option<*mut ::std::os::raw::c_void>) -> Result<(), NjError> {
39 let data_ptr = match data {
40 Some(ptr) => ptr,
41 None => ptr::null_mut(),
42 };
43 debug!("calling thread safe");
44 crate::napi_call_result!(crate::sys::napi_call_threadsafe_function(
45 self.tf,
46 data_ptr,
47 crate::sys::napi_threadsafe_function_call_mode_napi_tsfn_blocking
48 ))
49 }
50}
51
52impl Drop for ThreadSafeFunction {
53 fn drop(&mut self) {
54 crate::napi_call_assert!(crate::sys::napi_release_threadsafe_function(
55 self.tf,
56 crate::sys::napi_threadsafe_function_release_mode_napi_tsfn_release
57 ));
58 }
59}