diff options
| author | Yuki Okushi <jtitor@2k36.org> | 2022-10-11 18:37:53 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-11 18:37:53 +0900 |
| commit | e0954cadc8a407bed951ff8d956b76236b7dd97c (patch) | |
| tree | ae1e218b65a19999e4738d28dd5ea1a6e13514f0 /library/std/src | |
| parent | 387df55f2628f6ab48f578f9fde6f2e5b4f40b57 (diff) | |
| parent | b0b9f5bc269f5c5c1330bf30d25faf85741b2d49 (diff) | |
| download | rust-e0954cadc8a407bed951ff8d956b76236b7dd97c.tar.gz rust-e0954cadc8a407bed951ff8d956b76236b7dd97c.zip | |
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
Diffstat (limited to 'library/std/src')
| -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 2de7da3793f..c29b22c69e7 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; @@ -851,10 +851,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 /// @@ -939,10 +951,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`]. @@ -1003,10 +1018,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); } //////////////////////////////////////////////////////////////////////////////// |
