fix(napi): do nothing in deferred if thread is destroyed (#1568)

This commit is contained in:
LongYinan 2023-04-15 18:58:53 +08:00 committed by GitHub
parent ad143df4e1
commit d9ff0b4ddf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 14 additions and 11 deletions

View file

@ -8,7 +8,7 @@ use std::sync::{
}; };
#[cfg(all(feature = "napi4", not(target_arch = "wasm32")))] #[cfg(all(feature = "napi4", not(target_arch = "wasm32")))]
use crate::bindgen_prelude::{CUSTOM_GC_TSFN, CUSTOM_GC_TSFN_CLOSED, THREADS_CAN_ACCESS_ENV}; use crate::bindgen_prelude::{CUSTOM_GC_TSFN, THREADS_CAN_ACCESS_ENV, THREAD_DESTROYED};
pub use crate::js_values::TypedArrayType; pub use crate::js_values::TypedArrayType;
use crate::{check_status, sys, Error, Result, Status}; use crate::{check_status, sys, Error, Result, Status};
@ -68,9 +68,7 @@ macro_rules! impl_typed_array {
if let Some((ref_, env)) = self.raw { if let Some((ref_, env)) = self.raw {
#[cfg(all(feature = "napi4", not(target_arch = "wasm32")))] #[cfg(all(feature = "napi4", not(target_arch = "wasm32")))]
{ {
if CUSTOM_GC_TSFN_CLOSED if THREAD_DESTROYED.with(|closed| closed.load(std::sync::atomic::Ordering::Relaxed)) {
.with(|closed| closed.load(std::sync::atomic::Ordering::Relaxed))
{
return; return;
} }
if !THREADS_CAN_ACCESS_ENV if !THREADS_CAN_ACCESS_ENV

View file

@ -10,7 +10,7 @@ use std::sync::Arc;
use std::sync::Mutex; use std::sync::Mutex;
#[cfg(all(feature = "napi4", not(target_arch = "wasm32")))] #[cfg(all(feature = "napi4", not(target_arch = "wasm32")))]
use crate::bindgen_prelude::{CUSTOM_GC_TSFN, CUSTOM_GC_TSFN_CLOSED, THREADS_CAN_ACCESS_ENV}; use crate::bindgen_prelude::{CUSTOM_GC_TSFN, THREADS_CAN_ACCESS_ENV, THREAD_DESTROYED};
use crate::{bindgen_prelude::*, check_status, sys, Result, ValueType}; use crate::{bindgen_prelude::*, check_status, sys, Result, ValueType};
#[cfg(all(debug_assertions, not(windows)))] #[cfg(all(debug_assertions, not(windows)))]
@ -36,8 +36,7 @@ impl Drop for Buffer {
if let Some((ref_, env)) = self.raw { if let Some((ref_, env)) = self.raw {
#[cfg(all(feature = "napi4", not(target_arch = "wasm32")))] #[cfg(all(feature = "napi4", not(target_arch = "wasm32")))]
{ {
if CUSTOM_GC_TSFN_CLOSED.with(|closed| closed.load(std::sync::atomic::Ordering::Relaxed)) if THREAD_DESTROYED.with(|closed| closed.load(std::sync::atomic::Ordering::Relaxed)) {
{
return; return;
} }
if !THREADS_CAN_ACCESS_ENV if !THREADS_CAN_ACCESS_ENV

View file

@ -170,7 +170,7 @@ pub(crate) static CUSTOM_GC_TSFN: AtomicPtr<sys::napi_threadsafe_function__> =
thread_local! { thread_local! {
// CustomGC ThreadsafeFunction may be deleted during the process exit. // CustomGC ThreadsafeFunction may be deleted during the process exit.
// And there may still some Buffer alive after that. // And there may still some Buffer alive after that.
pub(crate) static CUSTOM_GC_TSFN_CLOSED: AtomicBool = AtomicBool::new(false); pub(crate) static THREAD_DESTROYED: AtomicBool = AtomicBool::new(false);
} }
#[cfg(all(feature = "napi4", not(target_arch = "wasm32")))] #[cfg(all(feature = "napi4", not(target_arch = "wasm32")))]
// Store thread id of the thread that created the CustomGC ThreadsafeFunction. // Store thread id of the thread that created the CustomGC ThreadsafeFunction.
@ -674,7 +674,7 @@ unsafe extern "C" fn custom_gc_finalize(
finalize_data: *mut std::ffi::c_void, finalize_data: *mut std::ffi::c_void,
finalize_hint: *mut std::ffi::c_void, finalize_hint: *mut std::ffi::c_void,
) { ) {
CUSTOM_GC_TSFN_CLOSED.with(|closed| { THREAD_DESTROYED.with(|closed| {
closed.store(true, Ordering::Relaxed); closed.store(true, Ordering::Relaxed);
}); });
} }

View file

@ -3,7 +3,7 @@ use std::marker::PhantomData;
use std::os::raw::c_void; use std::os::raw::c_void;
use std::ptr; use std::ptr;
use crate::bindgen_runtime::ToNapiValue; use crate::bindgen_runtime::{ToNapiValue, THREAD_DESTROYED};
use crate::{check_status, JsError, JsObject, Value}; use crate::{check_status, JsError, JsObject, Value};
use crate::{sys, Env, Error, Result}; use crate::{sys, Env, Error, Result};
@ -106,6 +106,12 @@ extern "C" fn napi_resolve_deferred<Data: ToNapiValue, Resolver: FnOnce(Env) ->
context: *mut c_void, context: *mut c_void,
data: *mut c_void, data: *mut c_void,
) { ) {
#[cfg(not(target_arch = "wasm32"))]
{
if THREAD_DESTROYED.with(|closed| closed.load(std::sync::atomic::Ordering::Relaxed)) {
return;
}
}
let deferred = context as sys::napi_deferred; let deferred = context as sys::napi_deferred;
let resolver = unsafe { Box::from_raw(data as *mut Result<Resolver>) }; let resolver = unsafe { Box::from_raw(data as *mut Result<Resolver>) };
let result = resolver let result = resolver

View file

@ -31,6 +31,6 @@
"environmentVariables": { "environmentVariables": {
"TS_NODE_PROJECT": "../tsconfig.json" "TS_NODE_PROJECT": "../tsconfig.json"
}, },
"timeout": "5m" "timeout": "10m"
} }
} }