Skip to content

Commit

Permalink
lib/c-api: fix env_finalizer being ran everytime WrapperEnv was dropped
Browse files Browse the repository at this point in the history
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
  • Loading branch information
epilys committed May 6, 2022
1 parent 9acb23a commit 91f8544
Showing 1 changed file with 9 additions and 5 deletions.
14 changes: 9 additions & 5 deletions lib/c-api/src/wasm_c_api/externals/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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<Option<wasm_env_finalizer_t>>,
env_finalizer: Arc<Mutex<Option<wasm_env_finalizer_t>>>,
}

impl wasmer_api::WasmerEnv for WrapperEnv {}
Expand All @@ -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 _) };
}
}
}
}
}
Expand Down Expand Up @@ -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,
);
Expand Down

0 comments on commit 91f8544

Please sign in to comment.