@@ -26,60 +26,27 @@ cfg_if::cfg_if! {
26
26
/// * If it is called again on a different thread, it will wait in a loop
27
27
/// (waiting for the process to exit).
28
28
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 => {
70
36
// This is the first thread to call `unique_thread_exit`,
71
37
// and this is the first time it is called.
72
38
// 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 => {
75
42
// This is the first thread to call `unique_thread_exit`,
76
43
// but this is the second time it is called.
77
44
// Abort the process.
78
45
core:: panicking:: panic_nounwind( "std::process::exit called re-entrantly" )
79
- } else {
46
+ }
47
+ Some ( _) => {
80
48
// This is not the first thread to call `unique_thread_exit`.
81
49
// Pause until the process exits.
82
- // Park until the process exits.
83
50
drop( exiting_thread_id) ;
84
51
loop {
85
52
// Safety: libc::pause is safe to call.
0 commit comments