From b6cc09d5141c914d9951716d9c0bb392e612576f Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Fri, 6 May 2022 19:06:27 +0300 Subject: [PATCH] lib/c-api: fix env_finalizer being called everytime WrapperEnv was dropped We would like to run the environment finalizer callback only when the last reference to env pointer is dropped, which is when the Arc<_> reference count is one. Closes #2871 --- lib/c-api/src/wasm_c_api/externals/function.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) 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 7db2b533d4d..da8d851fe38 100644 --- a/lib/c-api/src/wasm_c_api/externals/function.rs +++ b/lib/c-api/src/wasm_c_api/externals/function.rs @@ -6,7 +6,7 @@ use super::CApiExternTag; use std::convert::TryInto; use std::ffi::c_void; use std::mem::MaybeUninit; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use wasmer_api::{Function, RuntimeError, Val}; #[derive(Debug, Clone)] @@ -110,7 +110,7 @@ pub unsafe extern "C" fn wasm_func_new_with_env( #[repr(C)] struct WrapperEnv { env: *mut c_void, - env_finalizer: Arc>, + env_finalizer: Arc>>, } impl wasmer_api::WasmerEnv for WrapperEnv {} @@ -122,8 +122,12 @@ pub unsafe extern "C" fn wasm_func_new_with_env( impl Drop for WrapperEnv { fn drop(&mut self) { - if let Some(env_finalizer) = *self.env_finalizer { - unsafe { (env_finalizer)(self.env as _) } + if let Ok(mut guard) = self.env_finalizer.lock() { + if Arc::strong_count(&self.env_finalizer) == 1 { + if let Some(env_finalizer) = guard.take() { + unsafe { (env_finalizer)(self.env as _) }; + } + } } } } @@ -166,7 +170,7 @@ pub unsafe extern "C" fn wasm_func_new_with_env( func_sig, WrapperEnv { env, - env_finalizer: Arc::new(env_finalizer), + env_finalizer: Arc::new(Mutex::new(env_finalizer)), }, trampoline, );