Add/reorganize locks for thread synchronization (#1995)
Attempt to fix data races when using threads. - Protect access (from multiple threads) to exception and memory - Fix shared memory lock usage
This commit is contained in:
@ -194,7 +194,7 @@ runtime_signal_handler(void *sig_addr)
|
||||
else if (exec_env_tls->exce_check_guard_page <= (uint8 *)sig_addr
|
||||
&& (uint8 *)sig_addr
|
||||
< exec_env_tls->exce_check_guard_page + page_size) {
|
||||
bh_assert(wasm_get_exception(module_inst));
|
||||
bh_assert(wasm_copy_exception(module_inst, NULL));
|
||||
os_longjmp(jmpbuf_node->jmpbuf, 1);
|
||||
}
|
||||
}
|
||||
@ -250,7 +250,7 @@ runtime_exception_handler(EXCEPTION_POINTERS *exce_info)
|
||||
else if (exec_env_tls->exce_check_guard_page <= (uint8 *)sig_addr
|
||||
&& (uint8 *)sig_addr
|
||||
< exec_env_tls->exce_check_guard_page + page_size) {
|
||||
bh_assert(wasm_get_exception(module_inst));
|
||||
bh_assert(wasm_copy_exception(module_inst, NULL));
|
||||
if (module_inst->module_type == Wasm_Module_Bytecode) {
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
@ -1870,14 +1870,15 @@ static bool
|
||||
clear_wasi_proc_exit_exception(WASMModuleInstanceCommon *module_inst_comm)
|
||||
{
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
const char *exception;
|
||||
bool has_exception;
|
||||
char exception[EXCEPTION_BUF_LEN];
|
||||
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
|
||||
|
||||
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|
||||
|| module_inst_comm->module_type == Wasm_Module_AoT);
|
||||
|
||||
exception = wasm_get_exception(module_inst);
|
||||
if (exception && !strcmp(exception, "Exception: wasi proc exit")) {
|
||||
has_exception = wasm_copy_exception(module_inst, exception);
|
||||
if (has_exception && !strcmp(exception, "Exception: wasi proc exit")) {
|
||||
/* The "wasi proc exit" exception is thrown by native lib to
|
||||
let wasm app exit, which is a normal behavior, we clear
|
||||
the exception here. And just clear the exception of current
|
||||
@ -2306,6 +2307,12 @@ wasm_set_exception(WASMModuleInstance *module_inst, const char *exception)
|
||||
{
|
||||
WASMExecEnv *exec_env = NULL;
|
||||
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
WASMSharedMemNode *node =
|
||||
wasm_module_get_shared_memory((WASMModuleCommon *)module_inst->module);
|
||||
if (node)
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
#endif
|
||||
if (exception) {
|
||||
snprintf(module_inst->cur_exception, sizeof(module_inst->cur_exception),
|
||||
"Exception: %s", exception);
|
||||
@ -2313,6 +2320,10 @@ wasm_set_exception(WASMModuleInstance *module_inst, const char *exception)
|
||||
else {
|
||||
module_inst->cur_exception[0] = '\0';
|
||||
}
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
if (node)
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
exec_env =
|
||||
@ -2373,6 +2384,36 @@ wasm_get_exception(WASMModuleInstance *module_inst)
|
||||
return module_inst->cur_exception;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_copy_exception(WASMModuleInstance *module_inst, char *exception_buf)
|
||||
{
|
||||
bool has_exception = false;
|
||||
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
WASMSharedMemNode *node =
|
||||
wasm_module_get_shared_memory((WASMModuleCommon *)module_inst->module);
|
||||
if (node)
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
#endif
|
||||
if (module_inst->cur_exception[0] != '\0') {
|
||||
/* NULL is passed if the caller is not interested in getting the
|
||||
* exception content, but only in knowing if an exception has been
|
||||
* raised
|
||||
*/
|
||||
if (exception_buf != NULL)
|
||||
bh_memcpy_s(exception_buf, sizeof(module_inst->cur_exception),
|
||||
module_inst->cur_exception,
|
||||
sizeof(module_inst->cur_exception));
|
||||
has_exception = true;
|
||||
}
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
if (node)
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
#endif
|
||||
|
||||
return has_exception;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_set_exception(WASMModuleInstanceCommon *module_inst_comm,
|
||||
const char *exception)
|
||||
@ -2394,6 +2435,17 @@ wasm_runtime_get_exception(WASMModuleInstanceCommon *module_inst_comm)
|
||||
return wasm_get_exception(module_inst);
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_runtime_copy_exception(WASMModuleInstanceCommon *module_inst_comm,
|
||||
char *exception_buf)
|
||||
{
|
||||
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
|
||||
|
||||
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|
||||
|| module_inst_comm->module_type == Wasm_Module_AoT);
|
||||
return wasm_copy_exception(module_inst, exception_buf);
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_clear_exception(WASMModuleInstanceCommon *module_inst_comm)
|
||||
{
|
||||
@ -3317,7 +3369,7 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
|
||||
}
|
||||
}
|
||||
|
||||
ret = !wasm_runtime_get_exception(module) ? true : false;
|
||||
ret = !wasm_runtime_copy_exception(module, NULL);
|
||||
|
||||
fail:
|
||||
if (argv1 != argv_buf)
|
||||
@ -3792,7 +3844,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
||||
}
|
||||
exec_env->attachment = NULL;
|
||||
|
||||
ret = !wasm_runtime_get_exception(module) ? true : false;
|
||||
ret = !wasm_runtime_copy_exception(module, NULL);
|
||||
|
||||
fail:
|
||||
if (argv1 != argv_buf)
|
||||
@ -4006,7 +4058,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
||||
}
|
||||
exec_env->attachment = NULL;
|
||||
|
||||
ret = !wasm_runtime_get_exception(module) ? true : false;
|
||||
ret = !wasm_runtime_copy_exception(module, NULL);
|
||||
|
||||
fail:
|
||||
if (argv1 != argv_buf)
|
||||
@ -4333,7 +4385,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
||||
}
|
||||
exec_env->attachment = NULL;
|
||||
|
||||
ret = !wasm_runtime_get_exception(module) ? true : false;
|
||||
ret = !wasm_runtime_copy_exception(module, NULL);
|
||||
fail:
|
||||
if (argv1 != argv_buf)
|
||||
wasm_runtime_free(argv1);
|
||||
|
||||
Reference in New Issue
Block a user