chore(napi): show tips if create different buffers with same data
This commit is contained in:
parent
1d1c1706d5
commit
c605911cdf
2 changed files with 26 additions and 0 deletions
|
@ -1,10 +1,19 @@
|
|||
#[cfg(debug_assertions)]
|
||||
use std::collections::HashSet;
|
||||
use std::mem;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::ptr;
|
||||
use std::slice;
|
||||
#[cfg(debug_assertions)]
|
||||
use std::sync::Mutex;
|
||||
|
||||
use crate::{bindgen_prelude::*, check_status, sys, Result, ValueType};
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
thread_local! {
|
||||
pub (crate) static BUFFER_DATA: Mutex<HashSet<*mut u8>> = Default::default();
|
||||
}
|
||||
|
||||
/// Zero copy u8 vector shared between rust and napi.
|
||||
/// Auto reference the raw JavaScript value, and release it when dropped.
|
||||
/// So it is safe to use it in `async fn`, the `&[u8]` under the hood will not be dropped until the `drop` called.
|
||||
|
@ -53,6 +62,16 @@ impl Buffer {
|
|||
impl From<Vec<u8>> for Buffer {
|
||||
fn from(mut data: Vec<u8>) -> Self {
|
||||
let inner_ptr = data.as_mut_ptr();
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
let is_existed = BUFFER_DATA.with(|buffer_data| {
|
||||
let buffer = buffer_data.lock().expect("Unlock buffer data failed");
|
||||
buffer.contains(&inner_ptr)
|
||||
});
|
||||
if is_existed {
|
||||
panic!("Share the same data between different buffers is not allowed, see: https://github.com/nodejs/node/issues/32463#issuecomment-631974747");
|
||||
}
|
||||
}
|
||||
let len = data.len();
|
||||
let capacity = data.capacity();
|
||||
mem::forget(data);
|
||||
|
|
|
@ -52,6 +52,13 @@ pub unsafe extern "C" fn drop_buffer(
|
|||
finalize_hint: *mut c_void,
|
||||
) {
|
||||
let length_ptr = finalize_hint as *mut (usize, usize);
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
js_values::BUFFER_DATA.with(|buffer_data| {
|
||||
let mut buffer = buffer_data.lock().expect("Unlock Buffer data failed");
|
||||
buffer.remove(&(finalize_data as *mut u8));
|
||||
});
|
||||
}
|
||||
unsafe {
|
||||
let (length, cap) = *Box::from_raw(length_ptr);
|
||||
mem::drop(Vec::from_raw_parts(finalize_data as *mut u8, length, cap));
|
||||
|
|
Loading…
Reference in a new issue