Skip to content

Commit e0954ca

Browse files
authored
Rollup merge of #102412 - joboet:dont_panic, r=m-ou-se
Never panic in `thread::park` and `thread::park_timeout` fixes #102398 `@rustbot` label +T-libs +T-libs-api
2 parents 387df55 + b0b9f5b commit e0954ca

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;
@@ -851,10 +851,22 @@ pub fn sleep(dur: Duration) {
851851
imp::Thread::sleep(dur)
852852
}
853853

854+
/// Used to ensure that `park` and `park_timeout` do not unwind, as that can
855+
/// cause undefined behaviour if not handled correctly (see #102398 for context).
856+
struct PanicGuard;
857+
858+
impl Drop for PanicGuard {
859+
fn drop(&mut self) {
860+
rtabort!("an irrecoverable error occurred while synchronizing threads")
861+
}
862+
}
863+
854864
/// Blocks unless or until the current thread's token is made available.
855865
///
856866
/// A call to `park` does not guarantee that the thread will remain parked
857-
/// forever, and callers should be prepared for this possibility.
867+
/// forever, and callers should be prepared for this possibility. However,
868+
/// it is guaranteed that this function will not panic (it may abort the
869+
/// process if the implementation encounters some rare errors).
858870
///
859871
/// # park and unpark
860872
///
@@ -939,10 +951,13 @@ pub fn sleep(dur: Duration) {
939951
/// [`thread::park_timeout`]: park_timeout
940952
#[stable(feature = "rust1", since = "1.0.0")]
941953
pub fn park() {
954+
let guard = PanicGuard;
942955
// SAFETY: park_timeout is called on the parker owned by this thread.
943956
unsafe {
944957
current().inner.as_ref().parker().park();
945958
}
959+
// No panic occurred, do not abort.
960+
forget(guard);
946961
}
947962

948963
/// Use [`park_timeout`].
@@ -1003,10 +1018,13 @@ pub fn park_timeout_ms(ms: u32) {
10031018
/// ```
10041019
#[stable(feature = "park_timeout", since = "1.4.0")]
10051020
pub fn park_timeout(dur: Duration) {
1021+
let guard = PanicGuard;
10061022
// SAFETY: park_timeout is called on the parker owned by this thread.
10071023
unsafe {
10081024
current().inner.as_ref().parker().park_timeout(dur);
10091025
}
1026+
// No panic occurred, do not abort.
1027+
forget(guard);
10101028
}
10111029

10121030
////////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)