mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-15 06:01:14 +00:00
Fix thread manager issues (#962)
Fix the issue that joining a detached thread might result in joining hang, resolve the issue by adding wait_count for a thread's exec_env to indicate whether a thread needs to detach itself or not when it exits. And add checks for the input exec_env for cluster's join/detach/cancel thread.
This commit is contained in:
parent
ee97e30a1a
commit
092efbfe21
|
@ -98,6 +98,8 @@ typedef struct WASMExecEnv {
|
||||||
/* used to support debugger */
|
/* used to support debugger */
|
||||||
korp_mutex wait_lock;
|
korp_mutex wait_lock;
|
||||||
korp_cond wait_cond;
|
korp_cond wait_cond;
|
||||||
|
/* the count of threads which are joining current thread */
|
||||||
|
uint32 wait_count;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||||
|
|
|
@ -625,16 +625,69 @@ wasm_cluster_set_debug_inst(WASMCluster *cluster, WASMDebugInstance *inst)
|
||||||
|
|
||||||
#endif /* end of WASM_ENABLE_DEBUG_INTERP */
|
#endif /* end of WASM_ENABLE_DEBUG_INTERP */
|
||||||
|
|
||||||
|
/* Check whether the exec_env is in one of all clusters, the caller
|
||||||
|
should add lock to the cluster list before calling us */
|
||||||
|
static bool
|
||||||
|
clusters_have_exec_env(WASMExecEnv *exec_env)
|
||||||
|
{
|
||||||
|
WASMCluster *cluster = bh_list_first_elem(cluster_list);
|
||||||
|
WASMExecEnv *node;
|
||||||
|
|
||||||
|
while (cluster) {
|
||||||
|
node = bh_list_first_elem(&cluster->exec_env_list);
|
||||||
|
|
||||||
|
while (node) {
|
||||||
|
if (node == exec_env) {
|
||||||
|
bh_assert(exec_env->cluster == cluster);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
node = bh_list_elem_next(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
cluster = bh_list_elem_next(cluster);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int32
|
int32
|
||||||
wasm_cluster_join_thread(WASMExecEnv *exec_env, void **ret_val)
|
wasm_cluster_join_thread(WASMExecEnv *exec_env, void **ret_val)
|
||||||
{
|
{
|
||||||
return os_thread_join(exec_env->handle, ret_val);
|
korp_tid handle;
|
||||||
|
|
||||||
|
os_mutex_lock(&cluster_list_lock);
|
||||||
|
if (!clusters_have_exec_env(exec_env)) {
|
||||||
|
/* Invalid thread or the thread has exited */
|
||||||
|
if (ret_val)
|
||||||
|
*ret_val = NULL;
|
||||||
|
os_mutex_unlock(&cluster_list_lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
exec_env->wait_count++;
|
||||||
|
handle = exec_env->handle;
|
||||||
|
os_mutex_unlock(&cluster_list_lock);
|
||||||
|
return os_thread_join(handle, ret_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32
|
int32
|
||||||
wasm_cluster_detach_thread(WASMExecEnv *exec_env)
|
wasm_cluster_detach_thread(WASMExecEnv *exec_env)
|
||||||
{
|
{
|
||||||
return os_thread_detach(exec_env->handle);
|
int32 ret = 0;
|
||||||
|
|
||||||
|
os_mutex_lock(&cluster_list_lock);
|
||||||
|
if (!clusters_have_exec_env(exec_env)) {
|
||||||
|
/* Invalid thread or the thread has exited */
|
||||||
|
os_mutex_unlock(&cluster_list_lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (exec_env->wait_count == 0) {
|
||||||
|
/* Only detach current thread when there is no other thread
|
||||||
|
joining it, otherwise let the system resources for the
|
||||||
|
thread be released after joining */
|
||||||
|
ret = os_thread_detach(exec_env->handle);
|
||||||
|
}
|
||||||
|
os_mutex_unlock(&cluster_list_lock);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -680,6 +733,14 @@ wasm_cluster_exit_thread(WASMExecEnv *exec_env, void *retval)
|
||||||
int32
|
int32
|
||||||
wasm_cluster_cancel_thread(WASMExecEnv *exec_env)
|
wasm_cluster_cancel_thread(WASMExecEnv *exec_env)
|
||||||
{
|
{
|
||||||
|
os_mutex_lock(&cluster_list_lock);
|
||||||
|
if (!clusters_have_exec_env(exec_env)) {
|
||||||
|
/* Invalid thread or the thread has exited */
|
||||||
|
os_mutex_unlock(&cluster_list_lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
os_mutex_unlock(&cluster_list_lock);
|
||||||
|
|
||||||
/* Set the termination flag */
|
/* Set the termination flag */
|
||||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||||
wasm_cluster_thread_send_signal(exec_env, WAMR_SIG_TERM);
|
wasm_cluster_thread_send_signal(exec_env, WAMR_SIG_TERM);
|
||||||
|
|
|
@ -19,6 +19,7 @@ extern "C" {
|
||||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||||
typedef struct WASMDebugInstance WASMDebugInstance;
|
typedef struct WASMDebugInstance WASMDebugInstance;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct WASMCluster {
|
typedef struct WASMCluster {
|
||||||
struct WASMCluster *next;
|
struct WASMCluster *next;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user