diff options
| author | joboet <jonasboettiger@icloud.com> | 2022-09-28 16:54:00 +0200 |
|---|---|---|
| committer | joboet <jonasboettiger@icloud.com> | 2022-09-28 16:54:00 +0200 |
| commit | b0b9f5bc269f5c5c1330bf30d25faf85741b2d49 (patch) | |
| tree | f3d94aafc2439fc914c076a4e28b39940b932977 /library/std/src/thread | |
| parent | cba4a389b3961a2fd72e01bd6cb0b0e065edaf3d (diff) | |
| download | rust-b0b9f5bc269f5c5c1330bf30d25faf85741b2d49.tar.gz rust-b0b9f5bc269f5c5c1330bf30d25faf85741b2d49.zip | |
std: never panic in `thread::park` and `thread::park_timeout`
Diffstat (limited to 'library/std/src/thread')
| -rw-r--r-- | library/std/src/thread/mod.rs | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index ceea6986e33..54d611182e8 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -160,7 +160,7 @@ use crate::ffi::{CStr, CString}; use crate::fmt; use crate::io; use crate::marker::PhantomData; -use crate::mem; +use crate::mem::{self, forget}; use crate::num::NonZeroU64; use crate::num::NonZeroUsize; use crate::panic; @@ -849,10 +849,22 @@ pub fn sleep(dur: Duration) { imp::Thread::sleep(dur) } +/// Used to ensure that `park` and `park_timeout` do not unwind, as that can +/// cause undefined behaviour if not handled correctly (see #102398 for context). +struct PanicGuard; + +impl Drop for PanicGuard { + fn drop(&mut self) { + rtabort!("an irrecoverable error occurred while synchronizing threads") + } +} + /// Blocks unless or until the current thread's token is made available. /// /// A call to `park` does not guarantee that the thread will remain parked -/// forever, and callers should be prepared for this possibility. +/// forever, and callers should be prepared for this possibility. However, +/// it is guaranteed that this function will not panic (it may abort the +/// process if the implementation encounters some rare errors). /// /// # park and unpark /// @@ -937,10 +949,13 @@ pub fn sleep(dur: Duration) { /// [`thread::park_timeout`]: park_timeout #[stable(feature = "rust1", since = "1.0.0")] pub fn park() { + let guard = PanicGuard; // SAFETY: park_timeout is called on the parker owned by this thread. unsafe { current().inner.as_ref().parker().park(); } + // No panic occurred, do not abort. + forget(guard); } /// Use [`park_timeout`]. @@ -1001,10 +1016,13 @@ pub fn park_timeout_ms(ms: u32) { /// ``` #[stable(feature = "park_timeout", since = "1.4.0")] pub fn park_timeout(dur: Duration) { + let guard = PanicGuard; // SAFETY: park_timeout is called on the parker owned by this thread. unsafe { current().inner.as_ref().parker().park_timeout(dur); } + // No panic occurred, do not abort. + forget(guard); } //////////////////////////////////////////////////////////////////////////////// |
