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:
@@ -363,6 +363,40 @@ impl<T: ?Sized> Mutex<T> {
|
|||||||
self.poison.get()
|
self.poison.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Clear the poisoned state from a mutex
|
||||||
|
///
|
||||||
|
/// If the mutex is poisoned, it will remain poisoned until this function is called
|
||||||
|
/// with a mutex guard. 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();
|
||||||
|
///
|
||||||
|
/// let guard = mutex.lock().unwrap_err().into_inner();
|
||||||
|
/// Mutex::clear_poison(&guard);
|
||||||
|
/// assert_eq!(mutex.is_poisoned(), false);
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
#[unstable(feature = "mutex_unpoison", issue = "none")]
|
||||||
|
pub fn clear_poison(guard: &MutexGuard<'_, T>) {
|
||||||
|
guard.lock.poison.clear();
|
||||||
|
}
|
||||||
|
|
||||||
/// Consumes this mutex, returning the underlying data.
|
/// Consumes this mutex, returning the underlying data.
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
|
|||||||
@@ -40,6 +40,11 @@ impl Flag {
|
|||||||
pub fn get(&self) -> bool {
|
pub fn get(&self) -> bool {
|
||||||
self.failed.load(Ordering::Relaxed)
|
self.failed.load(Ordering::Relaxed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn clear(&self) {
|
||||||
|
self.failed.store(false, Ordering::Relaxed)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Guard {
|
pub struct Guard {
|
||||||
|
|||||||
@@ -366,6 +366,40 @@ impl<T: ?Sized> RwLock<T> {
|
|||||||
self.poison.get()
|
self.poison.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Clear the poisoned state from a lock
|
||||||
|
///
|
||||||
|
/// If the lock is poisoned, it will remain poisoned until this function is called
|
||||||
|
/// with a write guard. 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();
|
||||||
|
///
|
||||||
|
/// let guard = lock.write().unwrap_err().into_inner();
|
||||||
|
/// RwLock::clear_poison(&guard);
|
||||||
|
/// assert_eq!(lock.is_poisoned(), false);
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
#[unstable(feature = "mutex_unpoison", issue = "none")]
|
||||||
|
pub fn clear_poison(guard: &RwLockWriteGuard<'_, T>) {
|
||||||
|
guard.lock.poison.clear();
|
||||||
|
}
|
||||||
|
|
||||||
/// Consumes this `RwLock`, returning the underlying data.
|
/// Consumes this `RwLock`, returning the underlying data.
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
|
|||||||
Reference in New Issue
Block a user