Skip to content

Commit

Permalink
Add functions to un-poison Mutex and RwLock
Browse files Browse the repository at this point in the history
  • Loading branch information
tmccombs committed Apr 26, 2022
1 parent 9ea4d41 commit fc38388
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 0 deletions.
34 changes: 34 additions & 0 deletions library/std/src/sync/mutex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,40 @@ impl<T: ?Sized> Mutex<T> {
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.
///
/// # Errors
Expand Down
5 changes: 5 additions & 0 deletions library/std/src/sync/poison.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ impl Flag {
pub fn get(&self) -> bool {
self.failed.load(Ordering::Relaxed)
}

#[inline]
pub fn clear(&self) {
self.failed.store(false, Ordering::Relaxed)
}
}

pub struct Guard {
Expand Down
34 changes: 34 additions & 0 deletions library/std/src/sync/rwlock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,40 @@ impl<T: ?Sized> RwLock<T> {
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.
///
/// # Errors
Expand Down

0 comments on commit fc38388

Please sign in to comment.