@@ -76,6 +76,58 @@ traverse_list(bh_list *l, list_visitor visitor, void *user_data)
7676 }
7777}
7878
79+ /* Assumes cluster->lock is locked */
80+ static bool
81+ safe_traverse_exec_env_list (WASMCluster * cluster , list_visitor visitor ,
82+ void * user_data )
83+ {
84+ Vector proc_nodes ;
85+ void * node ;
86+ bool ret = true;
87+
88+ if (!bh_vector_init (& proc_nodes , cluster -> exec_env_list .len , sizeof (void * ),
89+ false)) {
90+ ret = false;
91+ goto final ;
92+ }
93+
94+ node = bh_list_first_elem (& cluster -> exec_env_list );
95+
96+ while (node ) {
97+ bool already_processed = false;
98+ void * proc_node ;
99+ for (size_t i = 0 ; i < bh_vector_size (& proc_nodes ); i ++ ) {
100+ if (!bh_vector_get (& proc_nodes , i , & proc_node )) {
101+ ret = false;
102+ goto final ;
103+ }
104+ if (proc_node == node ) {
105+ already_processed = true;
106+ break ;
107+ }
108+ }
109+ if (already_processed ) {
110+ node = bh_list_elem_next (node );
111+ continue ;
112+ }
113+
114+ os_mutex_unlock (& cluster -> lock );
115+ visitor (node , user_data );
116+ os_mutex_lock (& cluster -> lock );
117+ if (!bh_vector_append (& proc_nodes , & node )) {
118+ ret = false;
119+ goto final ;
120+ }
121+
122+ node = bh_list_first_elem (& cluster -> exec_env_list );
123+ }
124+
125+ final :
126+ bh_vector_destroy (& proc_nodes );
127+
128+ return ret ;
129+ }
130+
79131/* The caller must lock cluster->lock */
80132static bool
81133allocate_aux_stack (WASMCluster * cluster , uint32 * start , uint32 * size )
@@ -299,7 +351,6 @@ wasm_cluster_del_exec_env(WASMCluster *cluster, WASMExecEnv *exec_env)
299351 os_mutex_unlock (& cluster -> debug_inst -> wait_lock );
300352 }
301353#endif
302-
303354 if (bh_list_remove (& cluster -> exec_env_list , exec_env ) != 0 )
304355 ret = false;
305356
@@ -724,16 +775,22 @@ wasm_cluster_join_thread(WASMExecEnv *exec_env, void **ret_val)
724775 korp_tid handle ;
725776
726777 os_mutex_lock (& cluster_list_lock );
778+ os_mutex_lock (& exec_env -> cluster -> lock );
779+
727780 if (!clusters_have_exec_env (exec_env ) || exec_env -> thread_is_detached ) {
728781 /* Invalid thread, thread has exited or thread has been detached */
729782 if (ret_val )
730783 * ret_val = NULL ;
784+ os_mutex_unlock (& exec_env -> cluster -> lock );
731785 os_mutex_unlock (& cluster_list_lock );
732786 return 0 ;
733787 }
734788 exec_env -> wait_count ++ ;
735789 handle = exec_env -> handle ;
790+
791+ os_mutex_unlock (& exec_env -> cluster -> lock );
736792 os_mutex_unlock (& cluster_list_lock );
793+
737794 return os_thread_join (handle , ret_val );
738795}
739796
@@ -816,15 +873,22 @@ int32
816873wasm_cluster_cancel_thread (WASMExecEnv * exec_env )
817874{
818875 os_mutex_lock (& cluster_list_lock );
876+ os_mutex_lock (& exec_env -> cluster -> lock );
877+
878+ if (!exec_env -> cluster ) {
879+ goto final ;
880+ }
819881 if (!clusters_have_exec_env (exec_env )) {
820882 /* Invalid thread or the thread has exited */
821- os_mutex_unlock (& cluster_list_lock );
822- return 0 ;
883+ goto final ;
823884 }
824- os_mutex_unlock (& cluster_list_lock );
825885
826886 set_thread_cancel_flags (exec_env );
827887
888+ final :
889+ os_mutex_unlock (& exec_env -> cluster -> lock );
890+ os_mutex_unlock (& cluster_list_lock );
891+
828892 return 0 ;
829893}
830894
@@ -846,11 +910,9 @@ wasm_cluster_terminate_all(WASMCluster *cluster)
846910{
847911 os_mutex_lock (& cluster -> lock );
848912 cluster -> processing = true;
849- os_mutex_unlock (& cluster -> lock );
850913
851- traverse_list ( & cluster -> exec_env_list , terminate_thread_visitor , NULL );
914+ safe_traverse_exec_env_list ( cluster , terminate_thread_visitor , NULL );
852915
853- os_mutex_lock (& cluster -> lock );
854916 cluster -> processing = false;
855917 os_mutex_unlock (& cluster -> lock );
856918}
@@ -861,12 +923,10 @@ wasm_cluster_terminate_all_except_self(WASMCluster *cluster,
861923{
862924 os_mutex_lock (& cluster -> lock );
863925 cluster -> processing = true;
864- os_mutex_unlock (& cluster -> lock );
865926
866- traverse_list ( & cluster -> exec_env_list , terminate_thread_visitor ,
867- (void * )exec_env );
927+ safe_traverse_exec_env_list ( cluster , terminate_thread_visitor ,
928+ (void * )exec_env );
868929
869- os_mutex_lock (& cluster -> lock );
870930 cluster -> processing = false;
871931 os_mutex_unlock (& cluster -> lock );
872932}
@@ -888,11 +948,9 @@ wams_cluster_wait_for_all(WASMCluster *cluster)
888948{
889949 os_mutex_lock (& cluster -> lock );
890950 cluster -> processing = true;
891- os_mutex_unlock (& cluster -> lock );
892951
893- traverse_list ( & cluster -> exec_env_list , wait_for_thread_visitor , NULL );
952+ safe_traverse_exec_env_list ( cluster , wait_for_thread_visitor , NULL );
894953
895- os_mutex_lock (& cluster -> lock );
896954 cluster -> processing = false;
897955 os_mutex_unlock (& cluster -> lock );
898956}
@@ -903,12 +961,10 @@ wasm_cluster_wait_for_all_except_self(WASMCluster *cluster,
903961{
904962 os_mutex_lock (& cluster -> lock );
905963 cluster -> processing = true;
906- os_mutex_unlock (& cluster -> lock );
907964
908- traverse_list ( & cluster -> exec_env_list , wait_for_thread_visitor ,
909- (void * )exec_env );
965+ safe_traverse_exec_env_list ( cluster , wait_for_thread_visitor ,
966+ (void * )exec_env );
910967
911- os_mutex_lock (& cluster -> lock );
912968 cluster -> processing = false;
913969 os_mutex_unlock (& cluster -> lock );
914970}
0 commit comments