11use crate :: error:: Error ;
22use crate :: fmt;
3+
4+ #[ cfg( panic = "unwind" ) ]
35use crate :: sync:: atomic:: { AtomicBool , Ordering } ;
6+ #[ cfg( panic = "unwind" ) ]
47use crate :: thread;
58
69pub struct Flag {
10+ #[ cfg( panic = "unwind" ) ]
711 failed : AtomicBool ,
812}
913
@@ -21,7 +25,10 @@ pub struct Flag {
2125impl Flag {
2226 #[ inline]
2327 pub const fn new ( ) -> Flag {
24- Flag { failed : AtomicBool :: new ( false ) }
28+ Flag {
29+ #[ cfg( panic = "unwind" ) ]
30+ failed : AtomicBool :: new ( false ) ,
31+ }
2532 }
2633
2734 /// Check the flag for an unguarded borrow, where we only care about existing poison.
@@ -33,29 +40,46 @@ impl Flag {
3340 /// Check the flag for a guarded borrow, where we may also set poison when `done`.
3441 #[ inline]
3542 pub fn guard ( & self ) -> LockResult < Guard > {
36- let ret = Guard { panicking : thread:: panicking ( ) } ;
43+ let ret = Guard {
44+ #[ cfg( panic = "unwind" ) ]
45+ panicking : thread:: panicking ( ) ,
46+ } ;
3747 if self . get ( ) { Err ( PoisonError :: new ( ret) ) } else { Ok ( ret) }
3848 }
3949
4050 #[ inline]
51+ #[ cfg( panic = "unwind" ) ]
4152 pub fn done ( & self , guard : & Guard ) {
4253 if !guard. panicking && thread:: panicking ( ) {
4354 self . failed . store ( true , Ordering :: Relaxed ) ;
4455 }
4556 }
4657
4758 #[ inline]
59+ #[ cfg( not( panic = "unwind" ) ) ]
60+ pub fn done ( & self , _guard : & Guard ) { }
61+
62+ #[ inline]
63+ #[ cfg( panic = "unwind" ) ]
4864 pub fn get ( & self ) -> bool {
4965 self . failed . load ( Ordering :: Relaxed )
5066 }
5167
68+ #[ inline( always) ]
69+ #[ cfg( not( panic = "unwind" ) ) ]
70+ pub fn get ( & self ) -> bool {
71+ false
72+ }
73+
5274 #[ inline]
5375 pub fn clear ( & self ) {
76+ #[ cfg( panic = "unwind" ) ]
5477 self . failed . store ( false , Ordering :: Relaxed )
5578 }
5679}
5780
5881pub struct Guard {
82+ #[ cfg( panic = "unwind" ) ]
5983 panicking : bool ,
6084}
6185
@@ -95,6 +119,8 @@ pub struct Guard {
95119#[ stable( feature = "rust1" , since = "1.0.0" ) ]
96120pub struct PoisonError < T > {
97121 guard : T ,
122+ #[ cfg( not( panic = "unwind" ) ) ]
123+ _never : !,
98124}
99125
100126/// An enumeration of possible errors associated with a [`TryLockResult`] which
@@ -165,11 +191,27 @@ impl<T> PoisonError<T> {
165191 ///
166192 /// This is generally created by methods like [`Mutex::lock`](crate::sync::Mutex::lock)
167193 /// or [`RwLock::read`](crate::sync::RwLock::read).
194+ ///
195+ /// This method may panic if std was built with `panic="abort"`.
196+ #[ cfg( panic = "unwind" ) ]
168197 #[ stable( feature = "sync_poison" , since = "1.2.0" ) ]
169198 pub fn new ( guard : T ) -> PoisonError < T > {
170199 PoisonError { guard }
171200 }
172201
202+ /// Creates a `PoisonError`.
203+ ///
204+ /// This is generally created by methods like [`Mutex::lock`](crate::sync::Mutex::lock)
205+ /// or [`RwLock::read`](crate::sync::RwLock::read).
206+ ///
207+ /// This method may panic if std was built with `panic="abort"`.
208+ #[ cfg( not( panic = "unwind" ) ) ]
209+ #[ stable( feature = "sync_poison" , since = "1.2.0" ) ]
210+ #[ track_caller]
211+ pub fn new ( _guard : T ) -> PoisonError < T > {
212+ panic ! ( "PoisonError created in a libstd built with panic=\" abort\" " )
213+ }
214+
173215 /// Consumes this error indicating that a lock is poisoned, returning the
174216 /// underlying guard to allow access regardless.
175217 ///
@@ -225,6 +267,7 @@ impl<T> From<PoisonError<T>> for TryLockError<T> {
225267impl < T > fmt:: Debug for TryLockError < T > {
226268 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
227269 match * self {
270+ #[ cfg( panic = "unwind" ) ]
228271 TryLockError :: Poisoned ( ..) => "Poisoned(..)" . fmt ( f) ,
229272 TryLockError :: WouldBlock => "WouldBlock" . fmt ( f) ,
230273 }
@@ -235,6 +278,7 @@ impl<T> fmt::Debug for TryLockError<T> {
235278impl < T > fmt:: Display for TryLockError < T > {
236279 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
237280 match * self {
281+ #[ cfg( panic = "unwind" ) ]
238282 TryLockError :: Poisoned ( ..) => "poisoned lock: another task failed inside" ,
239283 TryLockError :: WouldBlock => "try_lock failed because the operation would block" ,
240284 }
@@ -247,6 +291,7 @@ impl<T> Error for TryLockError<T> {
247291 #[ allow( deprecated, deprecated_in_future) ]
248292 fn description ( & self ) -> & str {
249293 match * self {
294+ #[ cfg( panic = "unwind" ) ]
250295 TryLockError :: Poisoned ( ref p) => p. description ( ) ,
251296 TryLockError :: WouldBlock => "try_lock failed because the operation would block" ,
252297 }
@@ -255,6 +300,7 @@ impl<T> Error for TryLockError<T> {
255300 #[ allow( deprecated) ]
256301 fn cause ( & self ) -> Option < & dyn Error > {
257302 match * self {
303+ #[ cfg( panic = "unwind" ) ]
258304 TryLockError :: Poisoned ( ref p) => Some ( p) ,
259305 _ => None ,
260306 }
@@ -267,6 +313,7 @@ where
267313{
268314 match result {
269315 Ok ( t) => Ok ( f ( t) ) ,
316+ #[ cfg( panic = "unwind" ) ]
270317 Err ( PoisonError { guard } ) => Err ( PoisonError :: new ( f ( guard) ) ) ,
271318 }
272319}
0 commit comments