From 91f85443c12640da9037d722a8e9650fa7393c64 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 ran 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..bddeeb2e633 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 Arc::strong_count(&self.env_finalizer) == 1 { + if let Ok(mut guard) = self.env_finalizer.lock() { + 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, );