1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-11 08:33:43 -05:00

fix(napi): guard threadsafe function counters behind a mutex (#17552)

This commit is contained in:
Bartek Iwańczuk 2023-01-28 16:30:05 +01:00 committed by GitHub
parent fe11df09b1
commit 9cd271a9a5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -11,6 +11,7 @@ use deno_core::error::AnyError;
use deno_core::futures::channel::mpsc; use deno_core::futures::channel::mpsc;
use deno_core::futures::StreamExt; use deno_core::futures::StreamExt;
use deno_core::op; use deno_core::op;
use deno_core::parking_lot::Mutex;
use deno_core::serde_v8; use deno_core::serde_v8;
use deno_core::Extension; use deno_core::Extension;
use deno_core::OpState; use deno_core::OpState;
@ -338,7 +339,7 @@ pub struct NapiState {
mpsc::UnboundedSender<ThreadSafeFunctionStatus>, mpsc::UnboundedSender<ThreadSafeFunctionStatus>,
pub env_cleanup_hooks: pub env_cleanup_hooks:
Rc<RefCell<Vec<(extern "C" fn(*const c_void), *const c_void)>>>, Rc<RefCell<Vec<(extern "C" fn(*const c_void), *const c_void)>>>,
pub tsfn_ref_counters: Rc<RefCell<ThreadsafeFunctionRefCounters>>, pub tsfn_ref_counters: Arc<Mutex<ThreadsafeFunctionRefCounters>>,
} }
impl Drop for NapiState { impl Drop for NapiState {
@ -415,7 +416,7 @@ pub struct Env {
mpsc::UnboundedSender<ThreadSafeFunctionStatus>, mpsc::UnboundedSender<ThreadSafeFunctionStatus>,
pub cleanup_hooks: pub cleanup_hooks:
Rc<RefCell<Vec<(extern "C" fn(*const c_void), *const c_void)>>>, Rc<RefCell<Vec<(extern "C" fn(*const c_void), *const c_void)>>>,
pub tsfn_ref_counters: Rc<RefCell<ThreadsafeFunctionRefCounters>>, pub tsfn_ref_counters: Arc<Mutex<ThreadsafeFunctionRefCounters>>,
pub last_error: napi_extended_error_info, pub last_error: napi_extended_error_info,
} }
@ -431,7 +432,7 @@ impl Env {
cleanup_hooks: Rc< cleanup_hooks: Rc<
RefCell<Vec<(extern "C" fn(*const c_void), *const c_void)>>, RefCell<Vec<(extern "C" fn(*const c_void), *const c_void)>>,
>, >,
tsfn_ref_counters: Rc<RefCell<ThreadsafeFunctionRefCounters>>, tsfn_ref_counters: Arc<Mutex<ThreadsafeFunctionRefCounters>>,
) -> Self { ) -> Self {
let sc = sender.clone(); let sc = sender.clone();
ASYNC_WORK_SENDER.with(|s| { ASYNC_WORK_SENDER.with(|s| {
@ -498,13 +499,13 @@ impl Env {
id: usize, id: usize,
counter: Arc<AtomicUsize>, counter: Arc<AtomicUsize>,
) { ) {
let mut counters = self.tsfn_ref_counters.borrow_mut(); let mut counters = self.tsfn_ref_counters.lock();
assert!(!counters.iter().any(|(i, _)| *i == id)); assert!(!counters.iter().any(|(i, _)| *i == id));
counters.push((id, counter)); counters.push((id, counter));
} }
pub fn remove_threadsafe_function_ref_counter(&mut self, id: usize) { pub fn remove_threadsafe_function_ref_counter(&mut self, id: usize) {
let mut counters = self.tsfn_ref_counters.borrow_mut(); let mut counters = self.tsfn_ref_counters.lock();
let index = counters.iter().position(|(i, _)| *i == id).unwrap(); let index = counters.iter().position(|(i, _)| *i == id).unwrap();
counters.remove(index); counters.remove(index);
} }
@ -533,7 +534,7 @@ pub fn init<P: NapiPermissions + 'static>(unstable: bool) -> Extension {
maybe_scheduling = true; maybe_scheduling = true;
} }
let tsfn_ref_counters = napi_state.tsfn_ref_counters.borrow().clone(); let tsfn_ref_counters = napi_state.tsfn_ref_counters.lock().clone();
for (_id, counter) in tsfn_ref_counters.iter() { for (_id, counter) in tsfn_ref_counters.iter() {
if counter.load(std::sync::atomic::Ordering::SeqCst) > 0 { if counter.load(std::sync::atomic::Ordering::SeqCst) > 0 {
maybe_scheduling = true; maybe_scheduling = true;
@ -572,7 +573,7 @@ pub fn init<P: NapiPermissions + 'static>(unstable: bool) -> Extension {
threadsafe_function_receiver, threadsafe_function_receiver,
active_threadsafe_functions: 0, active_threadsafe_functions: 0,
env_cleanup_hooks: Rc::new(RefCell::new(vec![])), env_cleanup_hooks: Rc::new(RefCell::new(vec![])),
tsfn_ref_counters: Rc::new(RefCell::new(vec![])), tsfn_ref_counters: Arc::new(Mutex::new(vec![])),
}); });
state.put(Unstable(unstable)); state.put(Unstable(unstable));
Ok(()) Ok(())