@ -90,14 +90,7 @@ _Noreturn void __pthread_exit(void *result)
exit ( 0 ) ;
exit ( 0 ) ;
}
}
/* At this point we are committed to thread termination. Unlink
/* At this point we are committed to thread termination. */
* the thread from the list . This change will not be visible
* until the lock is released , which only happens after SYS_exit
* has been called , via the exit futex address pointing at the lock . */
libc . threads_minus_1 - - ;
self - > next - > prev = self - > prev ;
self - > prev - > next = self - > next ;
self - > prev = self - > next = self ;
/* Process robust list in userspace to handle non-pshared mutexes
/* Process robust list in userspace to handle non-pshared mutexes
* and the detached thread case where the robust list head will
* and the detached thread case where the robust list head will
@ -121,6 +114,16 @@ _Noreturn void __pthread_exit(void *result)
__do_orphaned_stdio_locks ( ) ;
__do_orphaned_stdio_locks ( ) ;
__dl_thread_cleanup ( ) ;
__dl_thread_cleanup ( ) ;
/* Last, unlink thread from the list. This change will not be visible
* until the lock is released , which only happens after SYS_exit
* has been called , via the exit futex address pointing at the lock .
* This needs to happen after any possible calls to LOCK ( ) that might
* skip locking if libc . threads_minus_1 is zero . */
libc . threads_minus_1 - - ;
self - > next - > prev = self - > prev ;
self - > prev - > next = self - > next ;
self - > prev = self - > next = self ;
/* This atomic potentially competes with a concurrent pthread_detach
/* This atomic potentially competes with a concurrent pthread_detach
* call ; the loser is responsible for freeing thread resources . */
* call ; the loser is responsible for freeing thread resources . */
int state = a_cas ( & self - > detach_state , DT_JOINABLE , DT_EXITING ) ;
int state = a_cas ( & self - > detach_state , DT_JOINABLE , DT_EXITING ) ;