@@ -160,7 +160,7 @@ use crate::ffi::{CStr, CString};
160
160
use crate :: fmt;
161
161
use crate :: io;
162
162
use crate :: marker:: PhantomData ;
163
- use crate :: mem;
163
+ use crate :: mem:: { self , forget } ;
164
164
use crate :: num:: NonZeroU64 ;
165
165
use crate :: num:: NonZeroUsize ;
166
166
use crate :: panic;
@@ -851,10 +851,22 @@ pub fn sleep(dur: Duration) {
851
851
imp:: Thread :: sleep ( dur)
852
852
}
853
853
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
+
854
864
/// Blocks unless or until the current thread's token is made available.
855
865
///
856
866
/// 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).
858
870
///
859
871
/// # park and unpark
860
872
///
@@ -939,10 +951,13 @@ pub fn sleep(dur: Duration) {
939
951
/// [`thread::park_timeout`]: park_timeout
940
952
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
941
953
pub fn park ( ) {
954
+ let guard = PanicGuard ;
942
955
// SAFETY: park_timeout is called on the parker owned by this thread.
943
956
unsafe {
944
957
current ( ) . inner . as_ref ( ) . parker ( ) . park ( ) ;
945
958
}
959
+ // No panic occurred, do not abort.
960
+ forget ( guard) ;
946
961
}
947
962
948
963
/// Use [`park_timeout`].
@@ -1003,10 +1018,13 @@ pub fn park_timeout_ms(ms: u32) {
1003
1018
/// ```
1004
1019
#[ stable( feature = "park_timeout" , since = "1.4.0" ) ]
1005
1020
pub fn park_timeout ( dur : Duration ) {
1021
+ let guard = PanicGuard ;
1006
1022
// SAFETY: park_timeout is called on the parker owned by this thread.
1007
1023
unsafe {
1008
1024
current ( ) . inner . as_ref ( ) . parker ( ) . park_timeout ( dur) ;
1009
1025
}
1026
+ // No panic occurred, do not abort.
1027
+ forget ( guard) ;
1010
1028
}
1011
1029
1012
1030
////////////////////////////////////////////////////////////////////////////////
0 commit comments