diff options
| author | Christiaan Dirkx <christiaan@dirkx.email> | 2021-04-21 10:05:11 +0200 |
|---|---|---|
| committer | Christiaan Dirkx <christiaan@dirkx.email> | 2021-04-22 10:27:21 +0200 |
| commit | 9cabbd0afcfd8aa5724501bea96fb98688913d0b (patch) | |
| tree | 1e562b85d2d3e1b9f472b7c4edf78758bbbd093b /library/std/src/sys_common | |
| parent | 71965ab4d05b023cd29c914ef1262a72cac02e01 (diff) | |
| download | rust-9cabbd0afcfd8aa5724501bea96fb98688913d0b.tar.gz rust-9cabbd0afcfd8aa5724501bea96fb98688913d0b.zip | |
Move `sys_common::poison` to `sync::poison`
Diffstat (limited to 'library/std/src/sys_common')
| -rw-r--r-- | library/std/src/sys_common/mod.rs | 1 | ||||
| -rw-r--r-- | library/std/src/sys_common/poison.rs | 257 |
2 files changed, 0 insertions, 258 deletions
diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs index 23a3a0e907d..4979bc0b5af 100644 --- a/library/std/src/sys_common/mod.rs +++ b/library/std/src/sys_common/mod.rs @@ -59,7 +59,6 @@ pub mod mutex; // when generating documentation. #[cfg(any(doc, not(windows)))] pub mod os_str_bytes; -pub mod poison; pub mod process; pub mod remutex; pub mod rwlock; diff --git a/library/std/src/sys_common/poison.rs b/library/std/src/sys_common/poison.rs deleted file mode 100644 index 1f71187f1b4..00000000000 --- a/library/std/src/sys_common/poison.rs +++ /dev/null @@ -1,257 +0,0 @@ -use crate::error::Error; -use crate::fmt; -use crate::sync::atomic::{AtomicBool, Ordering}; -use crate::thread; - -#[allow(unused_imports)] // for intra-doc links -use crate::sync::{Mutex, RwLock}; - -pub struct Flag { - failed: AtomicBool, -} - -// Note that the Ordering uses to access the `failed` field of `Flag` below is -// always `Relaxed`, and that's because this isn't actually protecting any data, -// it's just a flag whether we've panicked or not. -// -// The actual location that this matters is when a mutex is **locked** which is -// where we have external synchronization ensuring that we see memory -// reads/writes to this flag. -// -// As a result, if it matters, we should see the correct value for `failed` in -// all cases. - -impl Flag { - pub const fn new() -> Flag { - Flag { failed: AtomicBool::new(false) } - } - - #[inline] - pub fn borrow(&self) -> LockResult<Guard> { - let ret = Guard { panicking: thread::panicking() }; - if self.get() { Err(PoisonError::new(ret)) } else { Ok(ret) } - } - - #[inline] - pub fn done(&self, guard: &Guard) { - if !guard.panicking && thread::panicking() { - self.failed.store(true, Ordering::Relaxed); - } - } - - #[inline] - pub fn get(&self) -> bool { - self.failed.load(Ordering::Relaxed) - } -} - -pub struct Guard { - panicking: bool, -} - -/// A type of error which can be returned whenever a lock is acquired. -/// -/// Both [`Mutex`]es and [`RwLock`]s are poisoned whenever a thread fails while the lock -/// is held. The precise semantics for when a lock is poisoned is documented on -/// each lock, but once a lock is poisoned then all future acquisitions will -/// return this error. -/// -/// # Examples -/// -/// ``` -/// use std::sync::{Arc, Mutex}; -/// use std::thread; -/// -/// let mutex = Arc::new(Mutex::new(1)); -/// -/// // poison the mutex -/// let c_mutex = Arc::clone(&mutex); -/// let _ = thread::spawn(move || { -/// let mut data = c_mutex.lock().unwrap(); -/// *data = 2; -/// panic!(); -/// }).join(); -/// -/// match mutex.lock() { -/// Ok(_) => unreachable!(), -/// Err(p_err) => { -/// let data = p_err.get_ref(); -/// println!("recovered: {}", data); -/// } -/// }; -/// ``` -#[stable(feature = "rust1", since = "1.0.0")] -pub struct PoisonError<T> { - guard: T, -} - -/// An enumeration of possible errors associated with a [`TryLockResult`] which -/// can occur while trying to acquire a lock, from the [`try_lock`] method on a -/// [`Mutex`] or the [`try_read`] and [`try_write`] methods on an [`RwLock`]. -/// -/// [`try_lock`]: Mutex::try_lock -/// [`try_read`]: RwLock::try_read -/// [`try_write`]: RwLock::try_write -#[stable(feature = "rust1", since = "1.0.0")] -pub enum TryLockError<T> { - /// The lock could not be acquired because another thread failed while holding - /// the lock. - #[stable(feature = "rust1", since = "1.0.0")] - Poisoned(#[stable(feature = "rust1", since = "1.0.0")] PoisonError<T>), - /// The lock could not be acquired at this time because the operation would - /// otherwise block. - #[stable(feature = "rust1", since = "1.0.0")] - WouldBlock, -} - -/// A type alias for the result of a lock method which can be poisoned. -/// -/// The [`Ok`] variant of this result indicates that the primitive was not -/// poisoned, and the `Guard` is contained within. The [`Err`] variant indicates -/// that the primitive was poisoned. Note that the [`Err`] variant *also* carries -/// the associated guard, and it can be acquired through the [`into_inner`] -/// method. -/// -/// [`into_inner`]: PoisonError::into_inner -#[stable(feature = "rust1", since = "1.0.0")] -pub type LockResult<Guard> = Result<Guard, PoisonError<Guard>>; - -/// A type alias for the result of a nonblocking locking method. -/// -/// For more information, see [`LockResult`]. A `TryLockResult` doesn't -/// necessarily hold the associated guard in the [`Err`] type as the lock may not -/// have been acquired for other reasons. -#[stable(feature = "rust1", since = "1.0.0")] -pub type TryLockResult<Guard> = Result<Guard, TryLockError<Guard>>; - -#[stable(feature = "rust1", since = "1.0.0")] -impl<T> fmt::Debug for PoisonError<T> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("PoisonError").finish_non_exhaustive() - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<T> fmt::Display for PoisonError<T> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - "poisoned lock: another task failed inside".fmt(f) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<T> Error for PoisonError<T> { - #[allow(deprecated)] - fn description(&self) -> &str { - "poisoned lock: another task failed inside" - } -} - -impl<T> PoisonError<T> { - /// Creates a `PoisonError`. - /// - /// This is generally created by methods like [`Mutex::lock`] or [`RwLock::read`]. - #[stable(feature = "sync_poison", since = "1.2.0")] - pub fn new(guard: T) -> PoisonError<T> { - PoisonError { guard } - } - - /// Consumes this error indicating that a lock is poisoned, returning the - /// underlying guard to allow access regardless. - /// - /// # Examples - /// - /// ``` - /// use std::collections::HashSet; - /// use std::sync::{Arc, Mutex}; - /// use std::thread; - /// - /// let mutex = Arc::new(Mutex::new(HashSet::new())); - /// - /// // poison the mutex - /// let c_mutex = Arc::clone(&mutex); - /// let _ = thread::spawn(move || { - /// let mut data = c_mutex.lock().unwrap(); - /// data.insert(10); - /// panic!(); - /// }).join(); - /// - /// let p_err = mutex.lock().unwrap_err(); - /// let data = p_err.into_inner(); - /// println!("recovered {} items", data.len()); - /// ``` - #[stable(feature = "sync_poison", since = "1.2.0")] - pub fn into_inner(self) -> T { - self.guard - } - - /// Reaches into this error indicating that a lock is poisoned, returning a - /// reference to the underlying guard to allow access regardless. - #[stable(feature = "sync_poison", since = "1.2.0")] - pub fn get_ref(&self) -> &T { - &self.guard - } - - /// Reaches into this error indicating that a lock is poisoned, returning a - /// mutable reference to the underlying guard to allow access regardless. - #[stable(feature = "sync_poison", since = "1.2.0")] - pub fn get_mut(&mut self) -> &mut T { - &mut self.guard - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<T> From<PoisonError<T>> for TryLockError<T> { - fn from(err: PoisonError<T>) -> TryLockError<T> { - TryLockError::Poisoned(err) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<T> fmt::Debug for TryLockError<T> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self { - TryLockError::Poisoned(..) => "Poisoned(..)".fmt(f), - TryLockError::WouldBlock => "WouldBlock".fmt(f), - } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<T> fmt::Display for TryLockError<T> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self { - TryLockError::Poisoned(..) => "poisoned lock: another task failed inside", - TryLockError::WouldBlock => "try_lock failed because the operation would block", - } - .fmt(f) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<T> Error for TryLockError<T> { - #[allow(deprecated, deprecated_in_future)] - fn description(&self) -> &str { - match *self { - TryLockError::Poisoned(ref p) => p.description(), - TryLockError::WouldBlock => "try_lock failed because the operation would block", - } - } - - #[allow(deprecated)] - fn cause(&self) -> Option<&dyn Error> { - match *self { - TryLockError::Poisoned(ref p) => Some(p), - _ => None, - } - } -} - -pub fn map_result<T, U, F>(result: LockResult<T>, f: F) -> LockResult<U> -where - F: FnOnce(T) -> U, -{ - match result { - Ok(t) => Ok(f(t)), - Err(PoisonError { guard }) => Err(PoisonError::new(f(guard))), - } -} |
