@@ -60,6 +60,63 @@ static DWORD thread_data_key;
6060static void (WINAPI * GetCurrentThreadStackLimits_Kernel32 )(PULONG_PTR ,
6161 PULONG_PTR ) = NULL ;
6262
63+ static void
64+ thread_data_list_add (os_thread_data * thread_data )
65+ {
66+ os_mutex_lock (& thread_data_list_lock );
67+ /* If already in list, just return */
68+ os_thread_data * p = & supervisor_thread_data ;
69+ while (p ) {
70+ if (p == thread_data ) {
71+ os_mutex_unlock (& thread_data_list_lock );
72+ return ;
73+ }
74+ p = p -> next ;
75+ }
76+ thread_data -> next = supervisor_thread_data .next ;
77+ supervisor_thread_data .next = thread_data ;
78+ os_mutex_unlock (& thread_data_list_lock );
79+ }
80+
81+ static void
82+ thread_data_list_remove (os_thread_data * thread_data )
83+ {
84+ os_mutex_lock (& thread_data_list_lock );
85+ /* Search and remove it from list */
86+ os_thread_data * p = & supervisor_thread_data ;
87+ while (p && p -> next != thread_data )
88+ p = p -> next ;
89+
90+ if (p && p -> next ) {
91+ bh_assert (p -> next == thread_data );
92+ p -> next = p -> next -> next ;
93+ /* Release the resources in thread_data */
94+ os_cond_destroy (& thread_data -> wait_cond );
95+ os_mutex_destroy (& thread_data -> wait_lock );
96+ os_sem_destroy (& thread_data -> wait_node .sem );
97+ BH_FREE (thread_data );
98+ }
99+ os_mutex_unlock (& thread_data_list_lock );
100+ }
101+
102+ static os_thread_data *
103+ thread_data_list_lookup (korp_tid tid )
104+ {
105+ os_thread_data * thread_data = (os_thread_data * )tid ;
106+ os_mutex_lock (& thread_data_list_lock );
107+ os_thread_data * p = supervisor_thread_data .next ;
108+ while (p ) {
109+ if (p == thread_data ) {
110+ /* Found */
111+ os_mutex_unlock (& thread_data_list_lock );
112+ return p ;
113+ }
114+ p = p -> next ;
115+ }
116+ os_mutex_unlock (& thread_data_list_lock );
117+ return NULL ;
118+ }
119+
63120int
64121os_sem_init (korp_sem * sem );
65122int
@@ -254,10 +311,7 @@ os_thread_create_with_prio(korp_tid *p_tid, thread_start_routine_t start,
254311 }
255312
256313 /* Add thread data into thread data list */
257- os_mutex_lock (& thread_data_list_lock );
258- thread_data -> next = supervisor_thread_data .next ;
259- supervisor_thread_data .next = thread_data ;
260- os_mutex_unlock (& thread_data_list_lock );
314+ thread_data_list_add (thread_data );
261315
262316 /* Wait for the thread routine to set thread_data's tid
263317 and add thread_data to thread data list */
@@ -302,8 +356,12 @@ os_thread_join(korp_tid thread, void **p_retval)
302356 curr_thread_data -> wait_node .next = NULL ;
303357
304358 /* Get thread data of thread to join */
305- thread_data = (os_thread_data * )thread ;
306- bh_assert (thread_data );
359+ thread_data = thread_data_list_lookup (thread );
360+
361+ if (thread_data == NULL ) {
362+ os_printf ("Can't join thread %p, it does not exist" , thread );
363+ return BHT_ERROR ;
364+ }
307365
308366 os_mutex_lock (& thread_data -> wait_lock );
309367
@@ -312,6 +370,7 @@ os_thread_join(korp_tid thread, void **p_retval)
312370 if (p_retval )
313371 * p_retval = thread_data -> thread_retval ;
314372 os_mutex_unlock (& thread_data -> wait_lock );
373+ thread_data_list_remove (thread_data );
315374 return BHT_OK ;
316375 }
317376
@@ -332,6 +391,7 @@ os_thread_join(korp_tid thread, void **p_retval)
332391 os_sem_wait (& curr_thread_data -> wait_node .sem );
333392 if (p_retval )
334393 * p_retval = curr_thread_data -> wait_node .retval ;
394+ thread_data_list_remove (thread_data );
335395 return BHT_OK ;
336396}
337397
0 commit comments