diff --git a/CHANGELOG.md b/CHANGELOG.md index ff38fecb0b9..2a1b0ed5cc7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ - [#2056](https://github.com/wasmerio/wasmer/pull/2056) Change back to depend on the `enumset` crate instead of `wasmer_enumset` ### Fixed +- [#2084](https://github.com/wasmerio/wasmer/pull/2084) Avoid calling the function environment finalizer more than once when the environment has been cloned in the C API. - [#2069](https://github.com/wasmerio/wasmer/pull/2069) Use the new documentation for `include/README.md` in the Wasmer package. - [#2042](https://github.com/wasmerio/wasmer/pull/2042) Parse more exotic environment variables in `wasmer run`. - [#2041](https://github.com/wasmerio/wasmer/pull/2041) Documentation diagrams now have a solid white background rather than a transparent background. diff --git a/lib/c-api/src/wasm_c_api/externals/function.rs b/lib/c-api/src/wasm_c_api/externals/function.rs index 8b5a1cc40c2..d8fff4f2a2d 100644 --- a/lib/c-api/src/wasm_c_api/externals/function.rs +++ b/lib/c-api/src/wasm_c_api/externals/function.rs @@ -105,7 +105,7 @@ pub unsafe extern "C" fn wasm_func_new_with_env( #[repr(C)] struct WrapperEnv { env: *mut c_void, - finalizer: Option, + finalizer: Arc>, }; // 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, );