diff options
Diffstat (limited to 'ctr-std/src/sys_common/poison.rs')
| -rw-r--r-- | ctr-std/src/sys_common/poison.rs | 269 |
1 files changed, 0 insertions, 269 deletions
diff --git a/ctr-std/src/sys_common/poison.rs b/ctr-std/src/sys_common/poison.rs deleted file mode 100644 index 1625efe..0000000 --- a/ctr-std/src/sys_common/poison.rs +++ /dev/null @@ -1,269 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use error::{Error}; -use fmt; -use sync::atomic::{AtomicBool, Ordering}; -use thread; - -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 = mutex.clone(); -/// 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); -/// } -/// }; -/// ``` -/// -/// [`Mutex`]: ../../std/sync/struct.Mutex.html -/// [`RwLock`]: ../../std/sync/struct.RwLock.html -#[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`]. -/// -/// [`Mutex`]: struct.Mutex.html -/// [`RwLock`]: struct.RwLock.html -/// [`TryLockResult`]: type.TryLockResult.html -/// [`try_lock`]: struct.Mutex.html#method.try_lock -/// [`try_read`]: struct.RwLock.html#method.try_read -/// [`try_write`]: struct.RwLock.html#method.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. -/// -/// [`Ok`]: ../../std/result/enum.Result.html#variant.Ok -/// [`Err`]: ../../std/result/enum.Result.html#variant.Err -/// [`into_inner`]: ../../std/sync/struct.PoisonError.html#method.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. -/// -/// [`LockResult`]: ../../std/sync/type.LockResult.html -/// [`Err`]: ../../std/result/enum.Result.html#variant.Err -#[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 { - "PoisonError { inner: .. }".fmt(f) - } -} - -#[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> { - 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`]. - /// - /// [`Mutex::lock`]: ../../std/sync/struct.Mutex.html#method.lock - /// [`RwLock::read`]: ../../std/sync/struct.RwLock.html#method.read - #[stable(feature = "sync_poison", since = "1.2.0")] - pub fn new(guard: T) -> PoisonError<T> { - PoisonError { guard: 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 = mutex.clone(); - /// 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> { - fn description(&self) -> &str { - match *self { - TryLockError::Poisoned(ref p) => p.description(), - TryLockError::WouldBlock => "try_lock failed because the operation would block" - } - } - - 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))) - } -} |