From 24abeccccbdd024dec9b4768f7777155ea2590ca Mon Sep 17 00:00:00 2001 From: Julius Michaelis Date: Thu, 27 Jan 2022 23:06:35 +0900 Subject: [PATCH] Avoid deadlocks in emscripten dyn calls Do not hold locks on EmEnv's EmscriptenData into the actual call into the module --- lib/emscripten/src/emscripten_target.rs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/lib/emscripten/src/emscripten_target.rs b/lib/emscripten/src/emscripten_target.rs index d2dd03e07..7b1a43362 100644 --- a/lib/emscripten/src/emscripten_target.rs +++ b/lib/emscripten/src/emscripten_target.rs @@ -140,8 +140,8 @@ pub fn _getnameinfo( macro_rules! invoke { ($ctx: ident, $name:ident, $name_ref:ident, $( $arg:ident ),*) => {{ let sp = get_emscripten_data($ctx).stack_save_ref().expect("stack_save is None").call().expect("stack_save call failed"); - let result = get_emscripten_data($ctx).$name_ref().expect(concat!("Dynamic call is None: ", stringify!($name))).call($($arg),*); - match result { + let call = get_emscripten_data($ctx).$name_ref().expect(concat!("Dynamic call is None: ", stringify!($name))).clone(); + match call.call($($arg),*) { Ok(v) => v, Err(_e) => { get_emscripten_data($ctx).stack_restore_ref().expect("stack_restore is None").call(sp).expect("stack_restore call failed"); @@ -156,8 +156,8 @@ macro_rules! invoke { macro_rules! invoke_no_return { ($ctx: ident, $name:ident, $name_ref:ident, $( $arg:ident ),*) => {{ let sp = get_emscripten_data($ctx).stack_save_ref().expect("stack_save is None").call().expect("stack_save call failed"); - let result = get_emscripten_data($ctx).$name_ref().expect(concat!("Dynamic call is None: ", stringify!($name))).call($($arg),*); - match result { + let call = get_emscripten_data($ctx).$name_ref().expect(concat!("Dynamic call is None: ", stringify!($name))).clone(); + match call.call($($arg),*) { Ok(v) => v, Err(_e) => { get_emscripten_data($ctx).stack_restore_ref().expect("stack_restore is None").call(sp).expect("stack_restore call failed"); @@ -171,11 +171,9 @@ macro_rules! invoke_no_return { // The invoke_j functions do not save the stack macro_rules! invoke_no_stack_save { ($ctx: ident, $name:ident, $name_ref:ident, $( $arg:ident ),*) => {{ - if let Some(call) = get_emscripten_data($ctx).$name_ref() { - call.call($($arg),*).unwrap() - } else { - panic!("{} is set to None", stringify!($name)); - } + let call = get_emscripten_data($ctx).$name_ref().expect(concat!(stringify!($name), " is set to None")).clone(); + + call.call($($arg),*).unwrap() }} }