summaryrefslogtreecommitdiff
path: root/src/poisonable
diff options
context:
space:
mode:
Diffstat (limited to 'src/poisonable')
-rw-r--r--src/poisonable/poisonable.rs66
1 files changed, 59 insertions, 7 deletions
diff --git a/src/poisonable/poisonable.rs b/src/poisonable/poisonable.rs
index ff43ff8..e1c4caa 100644
--- a/src/poisonable/poisonable.rs
+++ b/src/poisonable/poisonable.rs
@@ -1,7 +1,7 @@
use std::marker::PhantomData;
use std::panic::{RefUnwindSafe, UnwindSafe};
-use crate::lockable::{Lockable, RawLock};
+use crate::lockable::{Lockable, LockableAsMut, LockableIntoInner, RawLock};
use crate::Keyable;
use super::{
@@ -282,9 +282,9 @@ impl<L: Lockable + RawLock> Poisonable<L> {
/// use happylock::{Mutex, Poisonable};
///
/// let mutex = Poisonable::new(Mutex::new(0));
- /// assert_eq!(mutex.into_inner().unwrap().into_inner(), 0);
+ /// assert_eq!(mutex.inner_lock().unwrap().into_inner(), 0);
/// ```
- pub fn into_inner(self) -> PoisonResult<L> {
+ pub fn inner_lock(self) -> PoisonResult<L> {
if self.is_poisoned() {
Err(PoisonError::new(self.inner))
} else {
@@ -294,6 +294,58 @@ impl<L: Lockable + RawLock> Poisonable<L> {
/// Returns a mutable reference to the underlying lock.
///
+ /// # Errors
+ ///
+ /// If another user of this lock panicked while holding the lock, then
+ /// this call will return an error instead.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use happylock::{Mutex, Poisonable, ThreadKey};
+ ///
+ /// let key = ThreadKey::get().unwrap();
+ /// let mut mutex = Poisonable::new(Mutex::new(0));
+ /// *mutex.lock_mut().unwrap().as_mut() = 10;
+ /// assert_eq!(*mutex.lock(key).unwrap(), 10);
+ /// ```
+ pub fn lock_mut(&mut self) -> PoisonResult<&mut L> {
+ if self.is_poisoned() {
+ Err(PoisonError::new(&mut self.inner))
+ } else {
+ Ok(&mut self.inner)
+ }
+ }
+}
+
+impl<L: LockableIntoInner + RawLock> Poisonable<L> {
+ /// Consumes this `Poisonable`, returning the underlying data.
+ ///
+ /// # Errors
+ ///
+ /// If another user of this lock panicked while holding the lock, then this
+ /// call will return an error instead.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use happylock::{Mutex, Poisonable};
+ ///
+ /// let mutex = Poisonable::new(Mutex::new(0));
+ /// assert_eq!(mutex.into_inner().unwrap(), 0);
+ /// ```
+ pub fn into_inner(self) -> PoisonResult<L::Inner> {
+ if self.is_poisoned() {
+ Err(PoisonError::new(self.inner.into_inner()))
+ } else {
+ Ok(self.inner.into_inner())
+ }
+ }
+}
+
+impl<L: LockableAsMut + RawLock> Poisonable<L> {
+ /// Returns a mutable reference to the underlying data.
+ ///
/// Since this call borrows the `Poisonable` mutable, no actual locking
/// needs to take place - the mutable borrow statically guarantees no locks
/// exist.
@@ -310,14 +362,14 @@ impl<L: Lockable + RawLock> Poisonable<L> {
///
/// let key = ThreadKey::get().unwrap();
/// let mut mutex = Poisonable::new(Mutex::new(0));
- /// *mutex.get_mut().unwrap().as_mut() = 10;
+ /// *mutex.get_mut().unwrap() = 10;
/// assert_eq!(*mutex.lock(key).unwrap(), 10);
/// ```
- pub fn get_mut(&mut self) -> PoisonResult<&mut L> {
+ pub fn get_mut(&mut self) -> PoisonResult<&mut L::Inner> {
if self.is_poisoned() {
- Err(PoisonError::new(&mut self.inner))
+ Err(PoisonError::new(self.inner.as_mut()))
} else {
- Ok(&mut self.inner)
+ Ok(self.inner.as_mut())
}
}
}