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::mem;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
use crate::{bindgen_prelude::*, check_status, sys, Result, ValueType};
|
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.
|
/// Zero copy u8 vector shared between rust and napi.
|
||||||
/// Auto reference the raw JavaScript value, and release it when dropped.
|
/// 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.
|
/// 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 {
|
impl From<Vec<u8>> for Buffer {
|
||||||
fn from(mut data: Vec<u8>) -> Self {
|
fn from(mut data: Vec<u8>) -> Self {
|
||||||
let inner_ptr = data.as_mut_ptr();
|
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 len = data.len();
|
||||||
let capacity = data.capacity();
|
let capacity = data.capacity();
|
||||||
mem::forget(data);
|
mem::forget(data);
|
||||||
|
|
|
@ -52,6 +52,13 @@ pub unsafe extern "C" fn drop_buffer(
|
||||||
finalize_hint: *mut c_void,
|
finalize_hint: *mut c_void,
|
||||||
) {
|
) {
|
||||||
let length_ptr = finalize_hint as *mut (usize, usize);
|
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 {
|
unsafe {
|
||||||
let (length, cap) = *Box::from_raw(length_ptr);
|
let (length, cap) = *Box::from_raw(length_ptr);
|
||||||
mem::drop(Vec::from_raw_parts(finalize_data as *mut u8, length, cap));
|
mem::drop(Vec::from_raw_parts(finalize_data as *mut u8, length, cap));
|
||||||
|
|
Loading…
Reference in a new issue