Use pthread_t instead of numeric thread id · model-checking/verify-rust-std@596be7e (original) (raw)

`@@ -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 = 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<Optionlibc::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.

`