Use libc::pause instead of std::thread::park in wait-for-exit loop · model-checking/verify-rust-std@2e90f6f (original) (raw)

`@@ -10,9 +10,9 @@ cfg_if::cfg_if! {

`

10

10

`} else if #[cfg(target_os = "linux")] {

`

11

11

`/// Mitigation for https://github.com/rust-lang/rust/issues/126600

`

12

12

`///

`

13

``

`` -

/// On unix (where libc::exit may not be thread-safe), ensure that only one Rust thread

``

14

``

`` -

/// calls libc::exit (or returns from main) by calling this function before calling

``

15

``

`` -

/// libc::exit (or returning from main).

``

``

13

`` +

/// On UNIX-like platforms (where libc::exit may not be thread-safe), ensure that only one

``

``

14

`` +

/// Rust thread calls libc::exit (or returns from main) by calling this function before

``

``

15

`` +

/// calling libc::exit (or returning from main).

``

16

16

`///

`

17

17

`/// Technically not enough to ensure soundness, since other code directly calling

`

18

18

`/// libc::exit will still race with this.

`

`@@ -23,7 +23,7 @@ cfg_if::cfg_if! {

`

23

23

`/// This function will return only the first time it is called in a process.

`

24

24

`///

`

25

25

`/// * If it is called again on the same thread as the first call, it will abort.

`

26

``

`` -

/// * If it is called again on a different thread, it will thread::park() in a loop

``

``

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

29

`let this_thread_id = unsafe { libc::gettid() };

`

`@@ -52,9 +52,10 @@ cfg_if::cfg_if! {

`

52

52

`}

`

53

53

`Err(_) => {

`

54

54

`` // This is not the first thread to call unique_thread_exit.

``

55

``

`-

// Park until the process exits.

`

``

55

`+

// Pause until the process exits.

`

56

56

`loop {

`

57

``

`-

crate::thread::park();

`

``

57

`+

// Safety: libc::pause is safe to call.

`

``

58

`+

unsafe { libc::pause(); }

`

58

59

`}

`

59

60

`}

`

60

61

`}

`

`@@ -77,10 +78,12 @@ cfg_if::cfg_if! {

`

77

78

` core::panicking::panic_nounwind("std::process::exit called re-entrantly")

`

78

79

`} else {

`

79

80

`` // This is not the first thread to call unique_thread_exit.

``

``

81

`+

// Pause until the process exits.

`

80

82

`// Park until the process exits.

`

81

83

` drop(exiting_thread_id);

`

82

84

`loop {

`

83

``

`-

crate::thread::park();

`

``

85

`+

// Safety: libc::pause is safe to call.

`

``

86

`+

unsafe { libc::pause(); }

`

84

87

`}

`

85

88

`}

`

86

89

`}

`