@@ -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;
@@ -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" ) ]
939951pub 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" ) ]
10031018pub 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