@@ -26,60 +26,27 @@ cfg_if::cfg_if! {
2626/// * If it is called again on a different thread, it will wait in a loop
2727/// (waiting for the process to exit).
2828pub ( crate ) fn unique_thread_exit( ) {
29- let this_thread_id =unsafe { libc:: gettid( ) } ;
30- debug_assert_ne!( this_thread_id, 0 , "thread ID cannot be zero" ) ;
31- #[ cfg( target_has_atomic ="32" ) ]
32- {
33- use crate :: sync:: atomic:: { AtomicI32 , Ordering } ;
34- static EXITING_THREAD_ID : AtomicI32 =AtomicI32 :: new( 0 ) ;
35- match EXITING_THREAD_ID . compare_exchange(
36- 0 ,
37- this_thread_id,
38- Ordering :: Relaxed ,
39- Ordering :: Relaxed ,
40- ) {
41- Ok ( _zero) =>{
42- // This is the first thread to call `unique_thread_exit`,
43- // and this is the first time it is called.
44- // Set EXITING_THREAD_ID to this thread's ID (done by the
45- // compare_exchange) and return.
46- }
47- Err ( id) if id == this_thread_id =>{
48- // This is the first thread to call `unique_thread_exit`,
49- // but this is the second time it is called.
50- // Abort the process.
51- core:: panicking:: panic_nounwind( "std::process::exit called re-entrantly" )
52- }
53- Err ( _) =>{
54- // This is not the first thread to call `unique_thread_exit`.
55- // Pause until the process exits.
56- loop {
57- // Safety: libc::pause is safe to call.
58- unsafe { libc:: pause( ) ; }
59- }
60- }
61- }
62- }
63- #[ cfg( not( target_has_atomic ="32" ) ) ]
64- {
65- use crate :: sync:: { Mutex , PoisonError } ;
66- static EXITING_THREAD_ID : Mutex <i32 > =Mutex :: new( 0 ) ;
67- let mut exiting_thread_id =
68- EXITING_THREAD_ID . lock( ) . unwrap_or_else( PoisonError :: into_inner) ;
69- if * exiting_thread_id ==0 {
29+ let this_thread_id =unsafe { libc:: pthread_self( ) } ;
30+ use crate :: sync:: { Mutex , PoisonError } ;
31+ static EXITING_THREAD_ID : Mutex <Option <libc:: pthread_t>> =Mutex :: new( None ) ;
32+ let mut exiting_thread_id =
33+ EXITING_THREAD_ID . lock( ) . unwrap_or_else( PoisonError :: into_inner) ;
34+ match * exiting_thread_id{
35+ None =>{
7036// This is the first thread to call `unique_thread_exit`,
7137// and this is the first time it is called.
7238// Set EXITING_THREAD_ID to this thread's ID and return.
73- * exiting_thread_id = this_thread_id;
74- } elseif * exiting_thread_id == this_thread_id{
39+ * exiting_thread_id =Some ( this_thread_id) ;
40+ } ,
41+ Some ( exiting_thread_id) if exiting_thread_id == this_thread_id =>{
7542// This is the first thread to call `unique_thread_exit`,
7643// but this is the second time it is called.
7744// Abort the process.
7845 core:: panicking:: panic_nounwind( "std::process::exit called re-entrantly" )
79- } else{
46+ }
47+ Some ( _) =>{
8048// This is not the first thread to call `unique_thread_exit`.
8149// Pause until the process exits.
82- // Park until the process exits.
8350 drop( exiting_thread_id) ;
8451loop {
8552// Safety: libc::pause is safe to call.