Skip to content

Commit 092efbf

Browse files
authored
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.
1 parent ee97e30 commit 092efbf

File tree

3 files changed

+66
-2
lines changed

3 files changed

+66
-2
lines changed

core/iwasm/common/wasm_exec_env.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ typedef struct WASMExecEnv {
9898
/* used to support debugger */
9999
korp_mutex wait_lock;
100100
korp_cond wait_cond;
101+
/* the count of threads which are joining current thread */
102+
uint32 wait_count;
101103
#endif
102104

103105
#if WASM_ENABLE_DEBUG_INTERP != 0

core/iwasm/libraries/thread-mgr/thread_manager.c

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -625,16 +625,69 @@ wasm_cluster_set_debug_inst(WASMCluster *cluster, WASMDebugInstance *inst)
625625

626626
#endif /* end of WASM_ENABLE_DEBUG_INTERP */
627627

628+
/* Check whether the exec_env is in one of all clusters, the caller
629+
should add lock to the cluster list before calling us */
630+
static bool
631+
clusters_have_exec_env(WASMExecEnv *exec_env)
632+
{
633+
WASMCluster *cluster = bh_list_first_elem(cluster_list);
634+
WASMExecEnv *node;
635+
636+
while (cluster) {
637+
node = bh_list_first_elem(&cluster->exec_env_list);
638+
639+
while (node) {
640+
if (node == exec_env) {
641+
bh_assert(exec_env->cluster == cluster);
642+
return true;
643+
}
644+
node = bh_list_elem_next(node);
645+
}
646+
647+
cluster = bh_list_elem_next(cluster);
648+
}
649+
650+
return false;
651+
}
652+
628653
int32
629654
wasm_cluster_join_thread(WASMExecEnv *exec_env, void **ret_val)
630655
{
631-
return os_thread_join(exec_env->handle, ret_val);
656+
korp_tid handle;
657+
658+
os_mutex_lock(&cluster_list_lock);
659+
if (!clusters_have_exec_env(exec_env)) {
660+
/* Invalid thread or the thread has exited */
661+
if (ret_val)
662+
*ret_val = NULL;
663+
os_mutex_unlock(&cluster_list_lock);
664+
return 0;
665+
}
666+
exec_env->wait_count++;
667+
handle = exec_env->handle;
668+
os_mutex_unlock(&cluster_list_lock);
669+
return os_thread_join(handle, ret_val);
632670
}
633671

634672
int32
635673
wasm_cluster_detach_thread(WASMExecEnv *exec_env)
636674
{
637-
return os_thread_detach(exec_env->handle);
675+
int32 ret = 0;
676+
677+
os_mutex_lock(&cluster_list_lock);
678+
if (!clusters_have_exec_env(exec_env)) {
679+
/* Invalid thread or the thread has exited */
680+
os_mutex_unlock(&cluster_list_lock);
681+
return 0;
682+
}
683+
if (exec_env->wait_count == 0) {
684+
/* Only detach current thread when there is no other thread
685+
joining it, otherwise let the system resources for the
686+
thread be released after joining */
687+
ret = os_thread_detach(exec_env->handle);
688+
}
689+
os_mutex_unlock(&cluster_list_lock);
690+
return ret;
638691
}
639692

640693
void
@@ -680,6 +733,14 @@ wasm_cluster_exit_thread(WASMExecEnv *exec_env, void *retval)
680733
int32
681734
wasm_cluster_cancel_thread(WASMExecEnv *exec_env)
682735
{
736+
os_mutex_lock(&cluster_list_lock);
737+
if (!clusters_have_exec_env(exec_env)) {
738+
/* Invalid thread or the thread has exited */
739+
os_mutex_unlock(&cluster_list_lock);
740+
return 0;
741+
}
742+
os_mutex_unlock(&cluster_list_lock);
743+
683744
/* Set the termination flag */
684745
#if WASM_ENABLE_DEBUG_INTERP != 0
685746
wasm_cluster_thread_send_signal(exec_env, WAMR_SIG_TERM);

core/iwasm/libraries/thread-mgr/thread_manager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ extern "C" {
1919
#if WASM_ENABLE_DEBUG_INTERP != 0
2020
typedef struct WASMDebugInstance WASMDebugInstance;
2121
#endif
22+
2223
typedef struct WASMCluster {
2324
struct WASMCluster *next;
2425

0 commit comments

Comments
 (0)