diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/collection/boxed.rs | 66 | ||||
| -rw-r--r-- | src/collection/owned.rs | 87 | ||||
| -rw-r--r-- | src/collection/ref.rs | 26 | ||||
| -rw-r--r-- | src/collection/retry.rs | 93 | ||||
| -rw-r--r-- | src/lockable.rs | 38 | ||||
| -rw-r--r-- | src/mutex/mutex.rs | 8 | ||||
| -rw-r--r-- | src/poisonable/poisonable.rs | 43 | ||||
| -rw-r--r-- | src/rwlock/rwlock.rs | 10 |
8 files changed, 237 insertions, 134 deletions
diff --git a/src/collection/boxed.rs b/src/collection/boxed.rs index 3766bed..fca1db2 100644 --- a/src/collection/boxed.rs +++ b/src/collection/boxed.rs @@ -3,7 +3,7 @@ use std::cell::UnsafeCell; use std::fmt::Debug; use std::marker::PhantomData; -use crate::lockable::{Lockable, OwnedLockable, RawLock, Sharable}; +use crate::lockable::{Lockable, LockableIntoInner, OwnedLockable, RawLock, Sharable}; use crate::Keyable; use super::{utils, BoxedLockCollection, LockGuard}; @@ -17,7 +17,8 @@ fn contains_duplicates(l: &[&dyn RawLock]) -> bool { } l.windows(2) - .any(|window| std::ptr::eq(window[0], window[1])) + // NOTE: addr_eq is necessary because eq would also compare the v-table pointers + .any(|window| std::ptr::addr_eq(window[0], window[1])) } unsafe impl<L: Lockable> RawLock for BoxedLockCollection<L> { @@ -67,7 +68,7 @@ unsafe impl<L: Lockable> Lockable for BoxedLockCollection<L> { } unsafe fn guard(&self) -> Self::Guard<'_> { - self.data().guard() + self.child().guard() } } @@ -78,12 +79,20 @@ unsafe impl<L: Sharable> Sharable for BoxedLockCollection<L> { Self: 'g; unsafe fn read_guard(&self) -> Self::ReadGuard<'_> { - self.data().read_guard() + self.child().read_guard() } } unsafe impl<L: OwnedLockable> OwnedLockable for BoxedLockCollection<L> {} +impl<L: LockableIntoInner> LockableIntoInner for BoxedLockCollection<L> { + type Inner = L::Inner; + + fn into_inner(self) -> Self::Inner { + LockableIntoInner::into_inner(self.into_child()) + } +} + impl<L> IntoIterator for BoxedLockCollection<L> where L: IntoIterator, @@ -92,7 +101,7 @@ where type IntoIter = <L as IntoIterator>::IntoIter; fn into_iter(self) -> Self::IntoIter { - self.into_inner().into_iter() + self.into_child().into_iter() } } @@ -104,7 +113,7 @@ where type IntoIter = <&'a L as IntoIterator>::IntoIter; fn into_iter(self) -> Self::IntoIter { - self.data().into_iter() + self.child().into_iter() } } @@ -125,16 +134,20 @@ unsafe impl<L: Sync> Sync for BoxedLockCollection<L> {} impl<L> Drop for BoxedLockCollection<L> { #[mutants::skip] fn drop(&mut self) { - self.locks.clear(); + unsafe { + // safety: this collection will never be locked again + self.locks.clear(); + // safety: this was allocated using a box, and is now unique + let boxed: Box<UnsafeCell<L>> = Box::from_raw(self.data.cast_mut()); - // safety: this was allocated using a box - unsafe { std::alloc::dealloc(self.data.cast_mut().cast(), Layout::new::<UnsafeCell<L>>()) } + drop(boxed) + } } } -impl<L> AsRef<L> for BoxedLockCollection<L> { - fn as_ref(&self) -> &L { - self.data() +impl<T, L: AsRef<T>> AsRef<T> for BoxedLockCollection<L> { + fn as_ref(&self) -> &T { + self.child().as_ref() } } @@ -174,17 +187,24 @@ impl<L> BoxedLockCollection<L> { /// let lock = LockCollection::try_new(&data).unwrap(); /// /// let key = ThreadKey::get().unwrap(); - /// let guard = lock.into_inner().0.lock(key); + /// let guard = lock.into_child().0.lock(key); /// assert_eq!(*guard, 42); /// ``` #[must_use] - pub fn into_inner(self) -> L { - // safety: this is owned, so no other references exist - unsafe { self.data.read().into_inner() } + pub fn into_child(mut self) -> L { + unsafe { + // safety: this collection will never be locked again + self.locks.clear(); + // safety: this was allocated using a box, and is now unique + let boxed: Box<UnsafeCell<L>> = Box::from_raw(self.data.cast_mut()); + + boxed.into_inner() + } } /// Gets an immutable reference to the underlying data - fn data(&self) -> &L { + #[must_use] + pub fn child(&self) -> &L { unsafe { self.data .as_ref() @@ -338,7 +358,7 @@ impl<L: Lockable> BoxedLockCollection<L> { LockGuard { // safety: we've already acquired the lock - guard: self.data().guard(), + guard: self.child().guard(), key, _phantom: PhantomData, } @@ -361,11 +381,11 @@ impl<L: Lockable> BoxedLockCollection<L> { /// let lock = LockCollection::new(data); /// /// match lock.try_lock(key) { - /// Some(mut guard) => { + /// Ok(mut guard) => { /// *guard.0 += 1; /// *guard.1 = "1"; /// }, - /// None => unreachable!(), + /// Err(_) => unreachable!(), /// }; /// /// ``` @@ -379,7 +399,7 @@ impl<L: Lockable> BoxedLockCollection<L> { } // safety: we've acquired the locks - self.data().guard() + self.child().guard() }; Ok(LockGuard { @@ -442,7 +462,7 @@ impl<L: Sharable> BoxedLockCollection<L> { LockGuard { // safety: we've already acquired the lock - guard: self.data().read_guard(), + guard: self.child().read_guard(), key, _phantom: PhantomData, } @@ -485,7 +505,7 @@ impl<L: Sharable> BoxedLockCollection<L> { } // safety: we've acquired the locks - self.data().read_guard() + self.child().read_guard() }; Some(LockGuard { diff --git a/src/collection/owned.rs b/src/collection/owned.rs index 714ff01..e4cfe46 100644 --- a/src/collection/owned.rs +++ b/src/collection/owned.rs @@ -1,6 +1,8 @@ use std::marker::PhantomData; -use crate::lockable::{Lockable, LockableIntoInner, OwnedLockable, RawLock, Sharable}; +use crate::lockable::{ + Lockable, LockableGetMut, LockableIntoInner, OwnedLockable, RawLock, Sharable, +}; use crate::Keyable; use super::{utils, LockGuard, OwnedLockCollection}; @@ -67,6 +69,17 @@ unsafe impl<L: Lockable> Lockable for OwnedLockCollection<L> { } } +impl<L: LockableGetMut> LockableGetMut for OwnedLockCollection<L> { + type Inner<'a> + = L::Inner<'a> + where + Self: 'a; + + fn get_mut(&mut self) -> Self::Inner<'_> { + self.data.get_mut() + } +} + impl<L: LockableIntoInner> LockableIntoInner for OwnedLockCollection<L> { type Inner = L::Inner; @@ -115,9 +128,15 @@ impl<E: OwnedLockable + Extend<L>, L: OwnedLockable> Extend<L> for OwnedLockColl } } -impl<L: OwnedLockable> AsMut<L> for OwnedLockCollection<L> { - fn as_mut(&mut self) -> &mut L { - &mut self.data +impl<T, L: AsRef<T>> AsRef<T> for OwnedLockCollection<L> { + fn as_ref(&self) -> &T { + self.data.as_ref() + } +} + +impl<T, L: AsMut<T>> AsMut<T> for OwnedLockCollection<L> { + fn as_mut(&mut self) -> &mut T { + self.data.as_mut() } } @@ -154,27 +173,6 @@ impl<L: OwnedLockable> OwnedLockCollection<L> { Self { data } } - /// Gets the underlying collection, consuming this collection. - /// - /// # Examples - /// - /// ``` - /// use happylock::{Mutex, ThreadKey}; - /// use happylock::collection::OwnedLockCollection; - /// - /// let data = (Mutex::new(42), Mutex::new("")); - /// let lock = OwnedLockCollection::new(data); - /// - /// let key = ThreadKey::get().unwrap(); - /// let inner = lock.into_inner(); - /// let guard = inner.0.lock(key); - /// assert_eq!(*guard, 42); - /// ``` - #[must_use] - pub fn into_inner(self) -> L { - self.data - } - /// Locks the collection /// /// This function returns a guard that can be used to access the underlying @@ -232,11 +230,11 @@ impl<L: OwnedLockable> OwnedLockCollection<L> { /// let lock = OwnedLockCollection::new(data); /// /// match lock.try_lock(key) { - /// Some(mut guard) => { + /// Ok(mut guard) => { /// *guard.0 += 1; /// *guard.1 = "1"; /// }, - /// None => unreachable!(), + /// Err(_) => unreachable!(), /// }; /// /// ``` @@ -397,6 +395,41 @@ impl<L: Sharable> OwnedLockCollection<L> { } } +impl<L> OwnedLockCollection<L> { + /// Gets the underlying collection, consuming this collection. + /// + /// # Examples + /// + /// ``` + /// use happylock::{Mutex, ThreadKey}; + /// use happylock::collection::OwnedLockCollection; + /// + /// let data = (Mutex::new(42), Mutex::new("")); + /// let lock = OwnedLockCollection::new(data); + /// + /// let key = ThreadKey::get().unwrap(); + /// let inner = lock.into_child(); + /// let guard = inner.0.lock(key); + /// assert_eq!(*guard, 42); + /// ``` + #[must_use] + pub fn into_child(self) -> L { + self.data + } +} + +impl<L: LockableGetMut> OwnedLockCollection<L> { + pub fn get_mut(&mut self) -> L::Inner<'_> { + LockableGetMut::get_mut(self) + } +} + +impl<L: LockableIntoInner> OwnedLockCollection<L> { + pub fn into_inner(self) -> L::Inner { + LockableIntoInner::into_inner(self) + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/collection/ref.rs b/src/collection/ref.rs index a9fc915..4fa5485 100644 --- a/src/collection/ref.rs +++ b/src/collection/ref.rs @@ -23,13 +23,8 @@ fn contains_duplicates(l: &[&dyn RawLock]) -> bool { } l.windows(2) - .any(|window| std::ptr::eq(window[0], window[1])) -} - -impl<L> AsRef<L> for RefLockCollection<'_, L> { - fn as_ref(&self) -> &L { - self.data - } + // NOTE: addr_eq is necessary because eq would also compare the v-table pointers + .any(|window| std::ptr::addr_eq(window[0], window[1])) } impl<'a, L> IntoIterator for &'a RefLockCollection<'a, L> @@ -106,6 +101,12 @@ unsafe impl<L: Sharable> Sharable for RefLockCollection<'_, L> { } } +impl<T, L: AsRef<T>> AsRef<T> for RefLockCollection<'_, L> { + fn as_ref(&self) -> &T { + self.data.as_ref() + } +} + impl<L: Debug> Debug for RefLockCollection<'_, L> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct(stringify!(RefLockCollection)) @@ -149,6 +150,13 @@ impl<'a, L: OwnedLockable> RefLockCollection<'a, L> { } } +impl<L> RefLockCollection<'_, L> { + #[must_use] + pub const fn child(&self) -> &L { + self.data + } +} + impl<'a, L: Lockable> RefLockCollection<'a, L> { /// Creates a new collections of locks. /// @@ -262,11 +270,11 @@ impl<'a, L: Lockable> RefLockCollection<'a, L> { /// let lock = RefLockCollection::new(&data); /// /// match lock.try_lock(key) { - /// Some(mut guard) => { + /// Ok(mut guard) => { /// *guard.0 += 1; /// *guard.1 = "1"; /// }, - /// None => unreachable!(), + /// Err(_) => unreachable!(), /// }; /// /// ``` diff --git a/src/collection/retry.rs b/src/collection/retry.rs index 0c44dea..3f5d471 100644 --- a/src/collection/retry.rs +++ b/src/collection/retry.rs @@ -1,7 +1,7 @@ use crate::collection::utils; use crate::handle_unwind::handle_unwind; use crate::lockable::{ - Lockable, LockableAsMut, LockableIntoInner, OwnedLockable, RawLock, Sharable, + Lockable, LockableGetMut, LockableIntoInner, OwnedLockable, RawLock, Sharable, }; use crate::Keyable; @@ -22,7 +22,8 @@ fn get_locks<L: Lockable>(data: &L) -> Vec<&dyn RawLock> { fn contains_duplicates<L: Lockable>(data: L) -> bool { let mut locks = Vec::new(); data.get_ptrs(&mut locks); - let locks = locks.into_iter().map(|l| &raw const *l); + // cast to *const () so that the v-table pointers are not used for hashing + let locks = locks.into_iter().map(|l| (&raw const *l).cast::<()>()); let mut locks_set = HashSet::with_capacity(locks.len()); for lock in locks { @@ -228,14 +229,14 @@ unsafe impl<L: Lockable> Lockable for RetryingLockCollection<L> { } } -impl<L: LockableAsMut> LockableAsMut for RetryingLockCollection<L> { +impl<L: LockableGetMut> LockableGetMut for RetryingLockCollection<L> { type Inner<'a> = L::Inner<'a> where Self: 'a; - fn as_mut(&mut self) -> Self::Inner<'_> { - self.data.as_mut() + fn get_mut(&mut self) -> Self::Inner<'_> { + self.data.get_mut() } } @@ -311,15 +312,15 @@ impl<E: OwnedLockable + Extend<L>, L: OwnedLockable> Extend<L> for RetryingLockC } } -impl<L> AsRef<L> for RetryingLockCollection<L> { - fn as_ref(&self) -> &L { - &self.data +impl<T, L: AsRef<T>> AsRef<T> for RetryingLockCollection<L> { + fn as_ref(&self) -> &T { + self.data.as_ref() } } -impl<L> AsMut<L> for RetryingLockCollection<L> { - fn as_mut(&mut self) -> &mut L { - &mut self.data +impl<T, L: AsMut<T>> AsMut<T> for RetryingLockCollection<L> { + fn as_mut(&mut self) -> &mut T { + self.data.as_mut() } } @@ -378,7 +379,7 @@ impl<'a, L: OwnedLockable> RetryingLockCollection<&'a L> { } } -impl<L: Lockable> RetryingLockCollection<L> { +impl<L> RetryingLockCollection<L> { /// Creates a new collections of locks. /// /// # Safety @@ -404,6 +405,37 @@ impl<L: Lockable> RetryingLockCollection<L> { Self { data } } + pub const fn child(&self) -> &L { + &self.data + } + + pub fn child_mut(&mut self) -> &mut L { + &mut self.data + } + + /// Gets the underlying collection, consuming this collection. + /// + /// # Examples + /// + /// ``` + /// use happylock::{Mutex, ThreadKey}; + /// use happylock::collection::RetryingLockCollection; + /// + /// let data = (Mutex::new(42), Mutex::new("")); + /// let lock = RetryingLockCollection::new(data); + /// + /// let key = ThreadKey::get().unwrap(); + /// let inner = lock.into_child(); + /// let guard = inner.0.lock(key); + /// assert_eq!(*guard, 42); + /// ``` + #[must_use] + pub fn into_child(self) -> L { + self.data + } +} + +impl<L: Lockable> RetryingLockCollection<L> { /// Creates a new collection of locks. /// /// This returns `None` if any locks are found twice in the given @@ -427,27 +459,6 @@ impl<L: Lockable> RetryingLockCollection<L> { (!contains_duplicates(&data)).then_some(Self { data }) } - /// Gets the underlying collection, consuming this collection. - /// - /// # Examples - /// - /// ``` - /// use happylock::{Mutex, ThreadKey}; - /// use happylock::collection::RetryingLockCollection; - /// - /// let data = (Mutex::new(42), Mutex::new("")); - /// let lock = RetryingLockCollection::new(data); - /// - /// let key = ThreadKey::get().unwrap(); - /// let inner = lock.into_inner(); - /// let guard = inner.0.lock(key); - /// assert_eq!(*guard, 42); - /// ``` - #[must_use] - pub fn into_inner(self) -> L { - self.data - } - /// Locks the collection /// /// This function returns a guard that can be used to access the underlying @@ -502,11 +513,11 @@ impl<L: Lockable> RetryingLockCollection<L> { /// let lock = RetryingLockCollection::new(data); /// /// match lock.try_lock(key) { - /// Some(mut guard) => { + /// Ok(mut guard) => { /// *guard.0 += 1; /// *guard.1 = "1"; /// }, - /// None => unreachable!(), + /// Err(_) => unreachable!(), /// }; /// /// ``` @@ -656,6 +667,18 @@ impl<L: Sharable> RetryingLockCollection<L> { } } +impl<L: LockableGetMut> RetryingLockCollection<L> { + pub fn get_mut(&mut self) -> L::Inner<'_> { + LockableGetMut::get_mut(self) + } +} + +impl<L: LockableIntoInner> RetryingLockCollection<L> { + pub fn into_inner(self) -> L::Inner { + LockableIntoInner::into_inner(self) + } +} + impl<'a, L: 'a> RetryingLockCollection<L> where &'a L: IntoIterator, diff --git a/src/lockable.rs b/src/lockable.rs index 5cc7135..1154d16 100644 --- a/src/lockable.rs +++ b/src/lockable.rs @@ -160,14 +160,14 @@ pub trait LockableIntoInner: Lockable { /// /// [`Poisonable`]: `crate::Poisonable` /// [`Poisonable::get_mut`]: `crate::poisonable::Poisonable::get_mut` -pub trait LockableAsMut: Lockable { +pub trait LockableGetMut: Lockable { /// The inner type that is behind the lock type Inner<'a> where Self: 'a; /// Returns a mutable reference to the underlying data. - fn as_mut(&mut self) -> Self::Inner<'_>; + fn get_mut(&mut self) -> Self::Inner<'_>; } /// Allows a lock to be accessed by multiple readers. @@ -239,14 +239,14 @@ unsafe impl<T: Lockable> Lockable for &mut T { } } -impl<T: LockableAsMut> LockableAsMut for &mut T { +impl<T: LockableGetMut> LockableGetMut for &mut T { type Inner<'a> = T::Inner<'a> where Self: 'a; - fn as_mut(&mut self) -> Self::Inner<'_> { - (*self).as_mut() + fn get_mut(&mut self) -> Self::Inner<'_> { + (*self).get_mut() } } @@ -283,11 +283,11 @@ macro_rules! tuple_impls { } } - impl<$($generic: LockableAsMut,)*> LockableAsMut for ($($generic,)*) { + impl<$($generic: LockableGetMut,)*> LockableGetMut for ($($generic,)*) { type Inner<'a> = ($($generic::Inner<'a>,)*) where Self: 'a; - fn as_mut(&mut self) -> Self::Inner<'_> { - ($(self.$value.as_mut(),)*) + fn get_mut(&mut self) -> Self::Inner<'_> { + ($(self.$value.get_mut(),)*) } } @@ -343,17 +343,17 @@ unsafe impl<T: Lockable, const N: usize> Lockable for [T; N] { } } -impl<T: LockableAsMut, const N: usize> LockableAsMut for [T; N] { +impl<T: LockableGetMut, const N: usize> LockableGetMut for [T; N] { type Inner<'a> = [T::Inner<'a>; N] where Self: 'a; - fn as_mut(&mut self) -> Self::Inner<'_> { + fn get_mut(&mut self) -> Self::Inner<'_> { unsafe { let mut guards = MaybeUninit::<[MaybeUninit<T::Inner<'_>>; N]>::uninit().assume_init(); for (i, lock) in self.iter_mut().enumerate() { - guards[i].write(lock.as_mut()); + guards[i].write(lock.get_mut()); } guards.map(|g| g.assume_init()) @@ -411,14 +411,14 @@ unsafe impl<T: Lockable> Lockable for Box<[T]> { } } -impl<T: LockableAsMut + 'static> LockableAsMut for Box<[T]> { +impl<T: LockableGetMut + 'static> LockableGetMut for Box<[T]> { type Inner<'a> = Box<[T::Inner<'a>]> where Self: 'a; - fn as_mut(&mut self) -> Self::Inner<'_> { - self.iter_mut().map(LockableAsMut::as_mut).collect() + fn get_mut(&mut self) -> Self::Inner<'_> { + self.iter_mut().map(LockableGetMut::get_mut).collect() } } @@ -469,14 +469,14 @@ unsafe impl<T: Lockable> Lockable for Vec<T> { // TODO: using edition 2024, impl LockableIntoInner for Box<[T]> -impl<T: LockableAsMut + 'static> LockableAsMut for Vec<T> { +impl<T: LockableGetMut + 'static> LockableGetMut for Vec<T> { type Inner<'a> = Box<[T::Inner<'a>]> where Self: 'a; - fn as_mut(&mut self) -> Self::Inner<'_> { - self.iter_mut().map(LockableAsMut::as_mut).collect() + fn get_mut(&mut self) -> Self::Inner<'_> { + self.iter_mut().map(LockableGetMut::get_mut).collect() } } @@ -571,7 +571,7 @@ mod tests { #[test] fn vec_as_mut() { let mut locks: Vec<Mutex<i32>> = vec![Mutex::new(1), Mutex::new(2)]; - let lock_ptrs = LockableAsMut::as_mut(&mut locks); + let lock_ptrs = LockableGetMut::get_mut(&mut locks); assert_eq!(lock_ptrs.len(), 2); assert_eq!(*lock_ptrs[0], 1); @@ -621,7 +621,7 @@ mod tests { #[test] fn box_as_mut() { let mut locks: Box<[Mutex<i32>]> = vec![Mutex::new(1), Mutex::new(2)].into_boxed_slice(); - let lock_ptrs = LockableAsMut::as_mut(&mut locks); + let lock_ptrs = LockableGetMut::get_mut(&mut locks); assert_eq!(lock_ptrs.len(), 2); assert_eq!(*lock_ptrs[0], 1); diff --git a/src/mutex/mutex.rs b/src/mutex/mutex.rs index 27a215f..4671b4f 100644 --- a/src/mutex/mutex.rs +++ b/src/mutex/mutex.rs @@ -7,7 +7,7 @@ use lock_api::RawMutex; use crate::handle_unwind::handle_unwind; use crate::key::Keyable; -use crate::lockable::{Lockable, LockableAsMut, LockableIntoInner, OwnedLockable, RawLock}; +use crate::lockable::{Lockable, LockableGetMut, LockableIntoInner, OwnedLockable, RawLock}; use crate::poisonable::PoisonFlag; use super::{Mutex, MutexGuard, MutexRef}; @@ -79,13 +79,13 @@ impl<T: Send, R: RawMutex + Send + Sync> LockableIntoInner for Mutex<T, R> { } } -impl<T: Send, R: RawMutex + Send + Sync> LockableAsMut for Mutex<T, R> { +impl<T: Send, R: RawMutex + Send + Sync> LockableGetMut for Mutex<T, R> { type Inner<'a> = &'a mut T where Self: 'a; - fn as_mut(&mut self) -> Self::Inner<'_> { + fn get_mut(&mut self) -> Self::Inner<'_> { self.get_mut() } } @@ -264,7 +264,7 @@ impl<T: ?Sized, R: RawMutex> Mutex<T, R> { /// thread::spawn(move || { /// let key = ThreadKey::get().unwrap(); /// let mut lock = c_mutex.try_lock(key); - /// if let Some(mut lock) = lock { + /// if let Ok(mut lock) = lock { /// *lock = 10; /// } else { /// println!("try_lock failed"); diff --git a/src/poisonable/poisonable.rs b/src/poisonable/poisonable.rs index 57436eb..79f90d9 100644 --- a/src/poisonable/poisonable.rs +++ b/src/poisonable/poisonable.rs @@ -2,7 +2,7 @@ use std::marker::PhantomData; use std::panic::{RefUnwindSafe, UnwindSafe}; use crate::lockable::{ - Lockable, LockableAsMut, LockableIntoInner, OwnedLockable, RawLock, Sharable, + Lockable, LockableGetMut, LockableIntoInner, OwnedLockable, RawLock, Sharable, }; use crate::Keyable; @@ -81,6 +81,33 @@ unsafe impl<L: Sharable> Sharable for Poisonable<L> { unsafe impl<L: OwnedLockable> OwnedLockable for Poisonable<L> {} +impl<L: LockableGetMut> LockableGetMut for Poisonable<L> { + type Inner<'a> + = PoisonResult<L::Inner<'a>> + where + Self: 'a; + + fn get_mut(&mut self) -> Self::Inner<'_> { + if self.is_poisoned() { + Err(PoisonError::new(self.inner.get_mut())) + } else { + Ok(self.inner.get_mut()) + } + } +} + +impl<L: LockableIntoInner> LockableIntoInner for Poisonable<L> { + type Inner = PoisonResult<L::Inner>; + + fn into_inner(self) -> Self::Inner { + if self.is_poisoned() { + Err(PoisonError::new(self.inner.into_inner())) + } else { + Ok(self.inner.into_inner()) + } + } +} + impl<L> From<L> for Poisonable<L> { fn from(value: L) -> Self { Self::new(value) @@ -524,15 +551,11 @@ impl<L: LockableIntoInner> Poisonable<L> { /// 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()) - } + LockableIntoInner::into_inner(self) } } -impl<L: LockableAsMut + RawLock> Poisonable<L> { +impl<L: LockableGetMut + RawLock> Poisonable<L> { /// Returns a mutable reference to the underlying data. /// /// Since this call borrows the `Poisonable` mutable, no actual locking @@ -555,11 +578,7 @@ impl<L: LockableAsMut + RawLock> Poisonable<L> { /// assert_eq!(*mutex.lock(key).unwrap(), 10); /// ``` pub fn get_mut(&mut self) -> PoisonResult<L::Inner<'_>> { - if self.is_poisoned() { - Err(PoisonError::new(self.inner.as_mut())) - } else { - Ok(self.inner.as_mut()) - } + LockableGetMut::get_mut(self) } } diff --git a/src/rwlock/rwlock.rs b/src/rwlock/rwlock.rs index 2c9ba22..66c7362 100644 --- a/src/rwlock/rwlock.rs +++ b/src/rwlock/rwlock.rs @@ -8,7 +8,7 @@ use lock_api::RawRwLock; use crate::handle_unwind::handle_unwind; use crate::key::Keyable; use crate::lockable::{ - Lockable, LockableAsMut, LockableIntoInner, OwnedLockable, RawLock, Sharable, + Lockable, LockableGetMut, LockableIntoInner, OwnedLockable, RawLock, Sharable, }; use super::{PoisonFlag, RwLock, RwLockReadGuard, RwLockReadRef, RwLockWriteGuard, RwLockWriteRef}; @@ -96,13 +96,13 @@ impl<T: Send, R: RawRwLock + Send + Sync> LockableIntoInner for RwLock<T, R> { } } -impl<T: Send, R: RawRwLock + Send + Sync> LockableAsMut for RwLock<T, R> { +impl<T: Send, R: RawRwLock + Send + Sync> LockableGetMut for RwLock<T, R> { type Inner<'a> = &'a mut T where Self: 'a; - fn as_mut(&mut self) -> Self::Inner<'_> { + fn get_mut(&mut self) -> Self::Inner<'_> { AsMut::as_mut(self) } } @@ -279,8 +279,8 @@ impl<T: ?Sized, R: RawRwLock> RwLock<T, R> { /// let lock = RwLock::new(1); /// /// match lock.try_read(key) { - /// Some(n) => assert_eq!(*n, 1), - /// None => unreachable!(), + /// Ok(n) => assert_eq!(*n, 1), + /// Err(_) => unreachable!(), /// }; /// ``` pub fn try_read<'s, 'key: 's, Key: Keyable>( |
