@@ -315,24 +315,18 @@ void _emscripten_thread_exit(void* result) {
315315 // Call into the musl function that runs destructors of all thread-specific data.
316316 __pthread_tsd_run_dtors ();
317317
318- // This atomic potentially competes with a concurrent pthread_detach
319- // call; the loser is responsible for freeing thread resources.
320- int state = a_cas (& self -> detach_state , DT_JOINABLE , DT_EXITING );
321-
322- // The thread list lock must be AS-safe.
323- __tl_lock ();
324-
325- // If this is the only thread in the list, don't proceed with
326- // termination of the thread, but restore the previous lock to
327- // prepare for exit to call atexit handlers.
328- if (self -> next == self ) {
329- __tl_unlock ();
330- self -> detach_state = state ;
318+ // If this is the main runtime thread, don't proceed with
319+ // termination of the thread, but prepare for exit to call
320+ // atexit handlers.
321+ if (emscripten_is_main_runtime_thread ()) {
331322 exit (0 );
332323 }
333324
334325 // At this point we are committed to thread termination.
335326
327+ // The thread list lock must be AS-safe.
328+ __tl_lock ();
329+
336330 // Process robust list in userspace to handle non-pshared mutexes
337331 // and the detached thread case where the robust list head will
338332 // be invalid when the kernel would process it.
@@ -367,6 +361,10 @@ void _emscripten_thread_exit(void* result) {
367361 // Not hosting a pthread anymore in this worker set __pthread_self to NULL
368362 __set_thread_state (NULL , 0 , 0 , 1 );
369363
364+ // This atomic potentially competes with a concurrent pthread_detach
365+ // call; the loser is responsible for freeing thread resources.
366+ int state = a_cas (& self -> detach_state , DT_JOINABLE , DT_EXITING );
367+
370368 if (state == DT_DETACHED ) {
371369 _emscripten_thread_cleanup (self );
372370 } else {
0 commit comments