From 2fe4ae1e2089530a21542fa0bb8eb9245cfdf04b Mon Sep 17 00:00:00 2001 From: Liang-Chi Hsieh Date: Sun, 13 Mar 2022 15:24:05 -0700 Subject: [PATCH] Clean up release after cloning source structs --- arrow/src/ffi.rs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/arrow/src/ffi.rs b/arrow/src/ffi.rs index 461995bdbaf9..019846782bc0 100644 --- a/arrow/src/ffi.rs +++ b/arrow/src/ffi.rs @@ -106,6 +106,11 @@ bitflags! { /// ABI-compatible struct for `ArrowSchema` from C Data Interface /// See /// This was created by bindgen +/// +/// Although this struct supports `Clone` but it is important to make sure +/// only one struct has the `release` callback after cloning. Otherwise +/// double-dropping can cause memory error. +/// #[repr(C)] #[derive(Debug, Clone)] pub struct FFI_ArrowSchema { @@ -116,7 +121,7 @@ pub struct FFI_ArrowSchema { n_children: i64, children: *mut *mut FFI_ArrowSchema, dictionary: *mut FFI_ArrowSchema, - release: Option, + pub(crate) release: Option, private_data: *mut c_void, } @@ -335,6 +340,11 @@ fn bit_width(data_type: &DataType, i: usize) -> Result { /// ABI-compatible struct for ArrowArray from C Data Interface /// See /// This was created by bindgen +/// +/// Although this struct supports `Clone` but it is important to make sure +/// only one struct has the `release` callback after cloning. Otherwise +/// double-dropping can cause memory error. +/// #[repr(C)] #[derive(Debug, Clone)] pub struct FFI_ArrowArray { @@ -346,7 +356,7 @@ pub struct FFI_ArrowArray { pub(crate) buffers: *mut *const c_void, children: *mut *mut FFI_ArrowArray, dictionary: *mut FFI_ArrowArray, - release: Option, + pub(crate) release: Option, // When exported, this MUST contain everything that is owned by this array. // for example, any buffer pointed to in `buffers` must be here, as well // as the `buffers` pointer itself. @@ -783,6 +793,11 @@ impl ArrowArray { }; let ffi_array = (*array).clone(); let ffi_schema = (*schema).clone(); + + // Clean up `release` of source structs + (*(array as *mut FFI_ArrowArray)).release = None; + (*(schema as *mut FFI_ArrowSchema)).release = None; + Ok(Self { array: Arc::new(ffi_array), schema: Arc::new(ffi_schema),