@@ -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;
@@ -849,10 +849,22 @@ pub fn sleep(dur: Duration) {
849
849
imp:: Thread :: sleep ( dur)
850
850
}
851
851
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
+
852
862
/// Blocks unless or until the current thread's token is made available.
853
863
///
854
864
/// 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).
856
868
///
857
869
/// # park and unpark
858
870
///
@@ -937,10 +949,13 @@ pub fn sleep(dur: Duration) {
937
949
/// [`thread::park_timeout`]: park_timeout
938
950
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
939
951
pub fn park ( ) {
952
+ let guard = PanicGuard ;
940
953
// SAFETY: park_timeout is called on the parker owned by this thread.
941
954
unsafe {
942
955
current ( ) . inner . as_ref ( ) . parker ( ) . park ( ) ;
943
956
}
957
+ // No panic occurred, do not abort.
958
+ forget ( guard) ;
944
959
}
945
960
946
961
/// Use [`park_timeout`].
@@ -1001,10 +1016,13 @@ pub fn park_timeout_ms(ms: u32) {
1001
1016
/// ```
1002
1017
#[ stable( feature = "park_timeout" , since = "1.4.0" ) ]
1003
1018
pub fn park_timeout ( dur : Duration ) {
1019
+ let guard = PanicGuard ;
1004
1020
// SAFETY: park_timeout is called on the parker owned by this thread.
1005
1021
unsafe {
1006
1022
current ( ) . inner . as_ref ( ) . parker ( ) . park_timeout ( dur) ;
1007
1023
}
1024
+ // No panic occurred, do not abort.
1025
+ forget ( guard) ;
1008
1026
}
1009
1027
1010
1028
////////////////////////////////////////////////////////////////////////////////
0 commit comments