mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-07 13:18:20 +00:00
fix(c-api) Avoid more than one call to the function environment finalizer.
A function environment `WrapperEnv` can be cloned. In case the original and the cloned environments are being dropped, the `self.finalizer` function —if any— is called twice. That's a bug. It must be called only once. This patch updates the code to apply the finalizer only once by taking it —if any— the first time it's called.
This commit is contained in:
16
lib/c-api/src/wasm_c_api/externals/function.rs
vendored
16
lib/c-api/src/wasm_c_api/externals/function.rs
vendored
@@ -105,7 +105,7 @@ pub unsafe extern "C" fn wasm_func_new_with_env(
|
||||
#[repr(C)]
|
||||
struct WrapperEnv {
|
||||
env: *mut c_void,
|
||||
finalizer: Option<wasm_env_finalizer_t>,
|
||||
finalizer: Arc<Option<wasm_env_finalizer_t>>,
|
||||
};
|
||||
|
||||
// Only relevant when using multiple threads in the C API;
|
||||
@@ -115,8 +115,13 @@ pub unsafe extern "C" fn wasm_func_new_with_env(
|
||||
|
||||
impl Drop for WrapperEnv {
|
||||
fn drop(&mut self) {
|
||||
if let Some(finalizer) = self.finalizer {
|
||||
unsafe { (finalizer)(self.env as _) }
|
||||
if let Some(finalizer) = Arc::get_mut(&mut self.finalizer)
|
||||
.map(Option::take)
|
||||
.flatten()
|
||||
{
|
||||
if !self.env.is_null() {
|
||||
unsafe { (finalizer)(self.env as _) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -160,7 +165,10 @@ pub unsafe extern "C" fn wasm_func_new_with_env(
|
||||
let function = Function::new_with_env(
|
||||
&store.inner,
|
||||
func_sig,
|
||||
WrapperEnv { env, finalizer },
|
||||
WrapperEnv {
|
||||
env,
|
||||
finalizer: Arc::new(finalizer),
|
||||
},
|
||||
inner_callback,
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user