Skip to content

Commit

Permalink
perf: register cleanup hook on global
Browse files Browse the repository at this point in the history
  • Loading branch information
SyMind committed Nov 28, 2024
1 parent 21edaba commit 111e3b3
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 18 deletions.
9 changes: 8 additions & 1 deletion crates/node_binding/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
extern crate napi_derive;
extern crate rspack_allocator;

use std::pin::Pin;
use std::sync::Mutex;
use std::{pin::Pin, sync::atomic};

use compiler::{Compiler, CompilerState, CompilerStateGuard};
use napi::bindgen_prelude::*;
Expand All @@ -26,6 +26,7 @@ use plugins::*;
use resolver_factory::*;
use rspack_binding_options::*;
use rspack_binding_values::*;
use rspack_napi::GLOBAL_CLEANUP_FLAG;
use rspack_tracing::chrome::FlushGuard;

#[napi]
Expand All @@ -48,6 +49,12 @@ impl Rspack {
) -> Result<Self> {
tracing::info!("raw_options: {:#?}", &options);

let _ = env.add_env_cleanup_hook((), move |_| {
if !GLOBAL_CLEANUP_FLAG.load(atomic::Ordering::Acquire) {
GLOBAL_CLEANUP_FLAG.fetch_and(true, atomic::Ordering::Release);
}
});

let mut plugins = Vec::new();
let js_plugin = JsHooksAdapterPlugin::from_js_hooks(env, register_js_taps)?;
plugins.push(js_plugin.clone().boxed());
Expand Down
23 changes: 6 additions & 17 deletions crates/rspack_napi/src/js_values/one_shot_value_ref.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
#![allow(clippy::not_unsafe_ptr_arg_deref)]

use std::cell::RefCell;
use std::marker::PhantomData;
use std::ptr;
use std::rc::Rc;
use std::sync::atomic::{self, AtomicBool};

use napi::bindgen_prelude::{
check_status, FromNapiMutRef, FromNapiRef, FromNapiValue, ToNapiValue,
};
use napi::sys::{self, napi_env};
use napi::{Env, Result};
use napi::Result;

// cleanup references to be executed when the JS thread exits normally
pub static GLOBAL_CLEANUP_FLAG: AtomicBool = AtomicBool::new(false);

// A RAII (Resource Acquisition Is Initialization) style wrapper around `Ref` that ensures the
// reference is unreferenced when it goes out of scope. This struct maintains a single reference
// count and automatically cleans up when it is dropped.
pub struct OneShotRef<T: 'static> {
env: napi_env,
napi_ref: sys::napi_ref,
cleanup_flag: Rc<RefCell<bool>>,
ty: PhantomData<T>,
}

Expand All @@ -28,20 +29,9 @@ impl<T: ToNapiValue + 'static> OneShotRef<T> {
let mut napi_ref = ptr::null_mut();
check_status!(unsafe { sys::napi_create_reference(env, napi_value, 1, &mut napi_ref) })?;

// cleanup references to be executed when the JS thread exits normally
let cleanup_flag = Rc::new(RefCell::new(false));
let env_wrapper = Env::from_raw(env);
let _ = env_wrapper.add_env_cleanup_hook(cleanup_flag.clone(), move |cleanup_flag| {
if !*cleanup_flag.borrow() {
*cleanup_flag.borrow_mut() = true;
unsafe { sys::napi_delete_reference(env, napi_ref) };
}
});

Ok(Self {
env,
napi_ref,
cleanup_flag,
ty: PhantomData,
})
}
Expand Down Expand Up @@ -91,8 +81,7 @@ impl<T: FromNapiMutRef + ToNapiValue + 'static> OneShotRef<T> {

impl<T> Drop for OneShotRef<T> {
fn drop(&mut self) {
if !*self.cleanup_flag.borrow() {
*self.cleanup_flag.borrow_mut() = true;
if !GLOBAL_CLEANUP_FLAG.load(atomic::Ordering::Acquire) {
unsafe { sys::napi_delete_reference(self.env, self.napi_ref) };
}
}
Expand Down

0 comments on commit 111e3b3

Please sign in to comment.