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
`}
`