summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/collection/boxed.rs66
-rw-r--r--src/collection/owned.rs87
-rw-r--r--src/collection/ref.rs26
-rw-r--r--src/collection/retry.rs93
-rw-r--r--src/lockable.rs38
-rw-r--r--src/mutex/mutex.rs8
-rw-r--r--src/poisonable/poisonable.rs43
-rw-r--r--src/rwlock/rwlock.rs10
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>(