Auto merge of #96422 - tmccombs:mutex-unpoison, r=m-ou-se
Add functions to un-poison Mutex and RwLock See discussion at https://internals.rust-lang.org/t/unpoisoning-a-mutex/16521/3
This commit is contained in:
commit
cd73afadae
@ -364,6 +364,45 @@ pub fn is_poisoned(&self) -> bool {
|
||||
self.poison.get()
|
||||
}
|
||||
|
||||
/// Clear the poisoned state from a mutex
|
||||
///
|
||||
/// If the mutex is poisoned, it will remain poisoned until this function is called. This
|
||||
/// allows recovering from a poisoned state and marking that it has recovered. For example, if
|
||||
/// the value is overwritten by a known-good value, then the mutex can be marked as
|
||||
/// un-poisoned. Or possibly, the value could be inspected to determine if it is in a
|
||||
/// consistent state, and if so the poison is removed.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(mutex_unpoison)]
|
||||
///
|
||||
/// use std::sync::{Arc, Mutex};
|
||||
/// use std::thread;
|
||||
///
|
||||
/// let mutex = Arc::new(Mutex::new(0));
|
||||
/// let c_mutex = Arc::clone(&mutex);
|
||||
///
|
||||
/// let _ = thread::spawn(move || {
|
||||
/// let _lock = c_mutex.lock().unwrap();
|
||||
/// panic!(); // the mutex gets poisoned
|
||||
/// }).join();
|
||||
///
|
||||
/// assert_eq!(mutex.is_poisoned(), true);
|
||||
/// let x = mutex.lock().unwrap_or_else(|mut e| {
|
||||
/// **e.get_mut() = 1;
|
||||
/// mutex.clear_poison();
|
||||
/// e.into_inner()
|
||||
/// });
|
||||
/// assert_eq!(mutex.is_poisoned(), false);
|
||||
/// assert_eq!(*x, 1);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "mutex_unpoison", issue = "96469")]
|
||||
pub fn clear_poison(&self) {
|
||||
self.poison.clear();
|
||||
}
|
||||
|
||||
/// Consumes this mutex, returning the underlying data.
|
||||
///
|
||||
/// # Errors
|
||||
|
@ -40,6 +40,11 @@ pub fn done(&self, guard: &Guard) {
|
||||
pub fn get(&self) -> bool {
|
||||
self.failed.load(Ordering::Relaxed)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn clear(&self) {
|
||||
self.failed.store(false, Ordering::Relaxed)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Guard {
|
||||
|
@ -368,6 +368,45 @@ pub fn is_poisoned(&self) -> bool {
|
||||
self.poison.get()
|
||||
}
|
||||
|
||||
/// Clear the poisoned state from a lock
|
||||
///
|
||||
/// If the lock is poisoned, it will remain poisoned until this function is called. This allows
|
||||
/// recovering from a poisoned state and marking that it has recovered. For example, if the
|
||||
/// value is overwritten by a known-good value, then the mutex can be marked as un-poisoned. Or
|
||||
/// possibly, the value could be inspected to determine if it is in a consistent state, and if
|
||||
/// so the poison is removed.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(mutex_unpoison)]
|
||||
///
|
||||
/// use std::sync::{Arc, RwLock};
|
||||
/// use std::thread;
|
||||
///
|
||||
/// let lock = Arc::new(RwLock::new(0));
|
||||
/// let c_lock = Arc::clone(&lock);
|
||||
///
|
||||
/// let _ = thread::spawn(move || {
|
||||
/// let _lock = c_lock.write().unwrap();
|
||||
/// panic!(); // the mutex gets poisoned
|
||||
/// }).join();
|
||||
///
|
||||
/// assert_eq!(lock.is_poisoned(), true);
|
||||
/// let guard = lock.write().unwrap_or_else(|mut e| {
|
||||
/// **e.get_mut() = 1;
|
||||
/// lock.clear_poison();
|
||||
/// e.into_inner()
|
||||
/// });
|
||||
/// assert_eq!(lock.is_poisoned(), false);
|
||||
/// assert_eq!(*guard, 1);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "mutex_unpoison", issue = "96469")]
|
||||
pub fn clear_poison(&self) {
|
||||
self.poison.clear();
|
||||
}
|
||||
|
||||
/// Consumes this `RwLock`, returning the underlying data.
|
||||
///
|
||||
/// # Errors
|
||||
|
Loading…
Reference in New Issue
Block a user