@@ -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).
2828 pub ( 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- } else if * 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) ;
8451 loop {
8552 // Safety: libc::pause is safe to call.
0 commit comments