Skip to content

Commit b0b9f5b

Browse files
committed
std: never panic in thread::park and thread::park_timeout
1 parent cba4a38 commit b0b9f5b

File tree

1 file changed

+20
-2
lines changed

1 file changed

+20
-2
lines changed

library/std/src/thread/mod.rs

+20-2
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ use crate::ffi::{CStr, CString};
160160
use crate::fmt;
161161
use crate::io;
162162
use crate::marker::PhantomData;
163-
use crate::mem;
163+
use crate::mem::{self, forget};
164164
use crate::num::NonZeroU64;
165165
use crate::num::NonZeroUsize;
166166
use crate::panic;
@@ -849,10 +849,22 @@ pub fn sleep(dur: Duration) {
849849
imp::Thread::sleep(dur)
850850
}
851851

852+
/// Used to ensure that `park` and `park_timeout` do not unwind, as that can
853+
/// cause undefined behaviour if not handled correctly (see #102398 for context).
854+
struct PanicGuard;
855+
856+
impl Drop for PanicGuard {
857+
fn drop(&mut self) {
858+
rtabort!("an irrecoverable error occurred while synchronizing threads")
859+
}
860+
}
861+
852862
/// Blocks unless or until the current thread's token is made available.
853863
///
854864
/// A call to `park` does not guarantee that the thread will remain parked
855-
/// forever, and callers should be prepared for this possibility.
865+
/// forever, and callers should be prepared for this possibility. However,
866+
/// it is guaranteed that this function will not panic (it may abort the
867+
/// process if the implementation encounters some rare errors).
856868
///
857869
/// # park and unpark
858870
///
@@ -937,10 +949,13 @@ pub fn sleep(dur: Duration) {
937949
/// [`thread::park_timeout`]: park_timeout
938950
#[stable(feature = "rust1", since = "1.0.0")]
939951
pub fn park() {
952+
let guard = PanicGuard;
940953
// SAFETY: park_timeout is called on the parker owned by this thread.
941954
unsafe {
942955
current().inner.as_ref().parker().park();
943956
}
957+
// No panic occurred, do not abort.
958+
forget(guard);
944959
}
945960

946961
/// Use [`park_timeout`].
@@ -1001,10 +1016,13 @@ pub fn park_timeout_ms(ms: u32) {
10011016
/// ```
10021017
#[stable(feature = "park_timeout", since = "1.4.0")]
10031018
pub fn park_timeout(dur: Duration) {
1019+
let guard = PanicGuard;
10041020
// SAFETY: park_timeout is called on the parker owned by this thread.
10051021
unsafe {
10061022
current().inner.as_ref().parker().park_timeout(dur);
10071023
}
1024+
// No panic occurred, do not abort.
1025+
forget(guard);
10081026
}
10091027

10101028
////////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)