@@ -160,7 +160,7 @@ use crate::ffi::{CStr, CString};
160160use crate :: fmt;
161161use crate :: io;
162162use crate :: marker:: PhantomData ;
163- use crate :: mem;
163+ use crate :: mem:: { self , forget } ;
164164use crate :: num:: NonZeroU64 ;
165165use crate :: num:: NonZeroUsize ;
166166use 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" ) ]
941953pub 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" ) ]
10051020pub 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