fix(napi): drop buffer inner data only when Reference count is 0
This commit is contained in:
parent
661b418eb6
commit
bffc49f11a
2 changed files with 18 additions and 8 deletions
|
@ -1,5 +1,6 @@
|
|||
#[cfg(debug_assertions)]
|
||||
use std::collections::HashSet;
|
||||
use std::ffi::c_void;
|
||||
use std::mem;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::ptr;
|
||||
|
@ -20,9 +21,9 @@ thread_local! {
|
|||
/// So it is safe to use it in `async fn`, the `&[u8]` under the hood will not be dropped until the `drop` called.
|
||||
/// Clone will create a new `Reference` to the same underlying `JavaScript Buffer`.
|
||||
pub struct Buffer {
|
||||
data_reference: Option<Arc<()>>,
|
||||
inner: &'static mut [u8],
|
||||
capacity: usize,
|
||||
pub(crate) data_reference: Option<Arc<()>>,
|
||||
pub(crate) inner: &'static mut [u8],
|
||||
pub(crate) capacity: usize,
|
||||
raw: Option<(sys::napi_ref, sys::napi_env)>,
|
||||
}
|
||||
|
||||
|
@ -181,13 +182,14 @@ impl ToNapiValue for Buffer {
|
|||
// the same data pointer if it's 0x0.
|
||||
unsafe { sys::napi_create_buffer(env, len, ptr::null_mut(), &mut ret) }
|
||||
} else {
|
||||
let val_ptr = val.inner.as_mut_ptr();
|
||||
unsafe {
|
||||
sys::napi_create_external_buffer(
|
||||
env,
|
||||
len,
|
||||
val.inner.as_mut_ptr() as *mut _,
|
||||
val_ptr as *mut c_void,
|
||||
Some(drop_buffer),
|
||||
Box::into_raw(Box::new((len, val.capacity))) as *mut _,
|
||||
Box::into_raw(Box::new(val)) as *mut c_void,
|
||||
&mut ret,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::ffi::c_void;
|
||||
use std::mem;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub use callback_info::*;
|
||||
pub use ctor::ctor;
|
||||
|
@ -66,7 +67,6 @@ pub unsafe extern "C" fn drop_buffer(
|
|||
finalize_data: *mut c_void,
|
||||
finalize_hint: *mut c_void,
|
||||
) {
|
||||
let length_ptr = finalize_hint as *mut (usize, usize);
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
js_values::BUFFER_DATA.with(|buffer_data| {
|
||||
|
@ -75,7 +75,15 @@ pub unsafe extern "C" fn drop_buffer(
|
|||
});
|
||||
}
|
||||
unsafe {
|
||||
let (length, cap) = *Box::from_raw(length_ptr);
|
||||
mem::drop(Vec::from_raw_parts(finalize_data as *mut u8, length, cap));
|
||||
let buf = Box::from_raw(finalize_hint as *mut Buffer);
|
||||
if let Some(data_reference) = buf.data_reference.as_ref() {
|
||||
if Arc::strong_count(data_reference) == 0 {
|
||||
mem::drop(Vec::from_raw_parts(
|
||||
finalize_data as *mut u8,
|
||||
buf.inner.len(),
|
||||
buf.capacity,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue