Skip to content

Commit

Permalink
lib/c-api: fix env_finalizer being called everytime WrapperEnv was dr…
Browse files Browse the repository at this point in the history
…opped

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 b6cc09d
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 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 _) };
}
}
}
}
}
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 b6cc09d

Please sign in to comment.