diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index 7531d5b058d..74692c1273c 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -228,6 +228,17 @@ impl Mutex { Err(TryLockError::WouldBlock) } } + + /// Determine whether the lock is poisoned. + /// + /// If another thread is active, the lock can still become poisoned at any + /// time. You should not trust a `false` value for program correctness + /// without additional synchronization. + #[inline] + #[unstable(feature = "std_misc")] + pub fn is_poisoned(&self) -> bool { + self.inner.poison.get() + } } #[unsafe_destructor] @@ -458,12 +469,14 @@ mod test { #[test] fn test_mutex_arc_poison() { let arc = Arc::new(Mutex::new(1)); + assert!(!arc.is_poisoned()); let arc2 = arc.clone(); let _ = Thread::scoped(move|| { let lock = arc2.lock().unwrap(); assert_eq!(*lock, 2); }).join(); assert!(arc.lock().is_err()); + assert!(arc.is_poisoned()); } #[test] diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs index 6efbcf89415..c4f1f2ccadd 100644 --- a/src/libstd/sync/rwlock.rs +++ b/src/libstd/sync/rwlock.rs @@ -237,6 +237,17 @@ impl RwLock { Err(TryLockError::WouldBlock) } } + + /// Determine whether the lock is poisoned. + /// + /// If another thread is active, the lock can still become poisoned at any + /// time. You should not trust a `false` value for program correctness + /// without additional synchronization. + #[inline] + #[unstable(feature = "std_misc")] + pub fn is_poisoned(&self) -> bool { + self.inner.poison.get() + } } #[unsafe_destructor] @@ -451,12 +462,14 @@ mod tests { #[test] fn test_rw_arc_poison_ww() { let arc = Arc::new(RwLock::new(1)); + assert!(!arc.is_poisoned()); let arc2 = arc.clone(); let _: Result = Thread::scoped(move|| { let _lock = arc2.write().unwrap(); panic!(); }).join(); assert!(arc.write().is_err()); + assert!(arc.is_poisoned()); } #[test]