diff options
Diffstat (limited to 'src/rwlock')
| -rw-r--r-- | src/rwlock/read_guard.rs | 71 | ||||
| -rw-r--r-- | src/rwlock/read_lock.rs | 34 | ||||
| -rw-r--r-- | src/rwlock/rwlock.rs | 130 | ||||
| -rw-r--r-- | src/rwlock/write_guard.rs | 75 | ||||
| -rw-r--r-- | src/rwlock/write_lock.rs | 25 |
5 files changed, 164 insertions, 171 deletions
diff --git a/src/rwlock/read_guard.rs b/src/rwlock/read_guard.rs index bd22837..0d68c75 100644 --- a/src/rwlock/read_guard.rs +++ b/src/rwlock/read_guard.rs @@ -5,34 +5,14 @@ use std::ops::Deref; use lock_api::RawRwLock; -use crate::key::Keyable; use crate::lockable::RawLock; +use crate::ThreadKey; use super::{RwLock, RwLockReadGuard, RwLockReadRef}; // These impls make things slightly easier because now you can use // `println!("{guard}")` instead of `println!("{}", *guard)` -impl<T: PartialEq + ?Sized, R: RawRwLock> PartialEq for RwLockReadRef<'_, T, R> { - fn eq(&self, other: &Self) -> bool { - self.deref().eq(&**other) - } -} - -impl<T: Eq + ?Sized, R: RawRwLock> Eq for RwLockReadRef<'_, T, R> {} - -impl<T: PartialOrd + ?Sized, R: RawRwLock> PartialOrd for RwLockReadRef<'_, T, R> { - fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { - self.deref().partial_cmp(&**other) - } -} - -impl<T: Ord + ?Sized, R: RawRwLock> Ord for RwLockReadRef<'_, T, R> { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.deref().cmp(&**other) - } -} - #[mutants::skip] // hashing involves PRNG and is hard to test #[cfg(not(tarpaulin_include))] impl<T: Hash + ?Sized, R: RawRwLock> Hash for RwLockReadRef<'_, T, R> { @@ -89,41 +69,9 @@ impl<'a, T: ?Sized, R: RawRwLock> RwLockReadRef<'a, T, R> { } } -#[mutants::skip] // it's hard to get two read guards safely -#[cfg(not(tarpaulin_include))] -impl<T: PartialEq + ?Sized, R: RawRwLock, Key: Keyable> PartialEq - for RwLockReadGuard<'_, '_, T, Key, R> -{ - fn eq(&self, other: &Self) -> bool { - self.deref().eq(&**other) - } -} - -#[mutants::skip] // it's hard to get two read guards safely -#[cfg(not(tarpaulin_include))] -impl<T: Eq + ?Sized, R: RawRwLock, Key: Keyable> Eq for RwLockReadGuard<'_, '_, T, Key, R> {} - -#[mutants::skip] // it's hard to get two read guards safely -#[cfg(not(tarpaulin_include))] -impl<T: PartialOrd + ?Sized, R: RawRwLock, Key: Keyable> PartialOrd - for RwLockReadGuard<'_, '_, T, Key, R> -{ - fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { - self.deref().partial_cmp(&**other) - } -} - -#[mutants::skip] // it's hard to get two read guards safely -#[cfg(not(tarpaulin_include))] -impl<T: Ord + ?Sized, R: RawRwLock, Key: Keyable> Ord for RwLockReadGuard<'_, '_, T, Key, R> { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.deref().cmp(&**other) - } -} - #[mutants::skip] // hashing involves PRNG and is hard to test #[cfg(not(tarpaulin_include))] -impl<T: Hash + ?Sized, R: RawRwLock, Key: Keyable> Hash for RwLockReadGuard<'_, '_, T, Key, R> { +impl<T: Hash + ?Sized, R: RawRwLock> Hash for RwLockReadGuard<'_, T, R> { fn hash<H: std::hash::Hasher>(&self, state: &mut H) { self.deref().hash(state) } @@ -131,21 +79,19 @@ impl<T: Hash + ?Sized, R: RawRwLock, Key: Keyable> Hash for RwLockReadGuard<'_, #[mutants::skip] #[cfg(not(tarpaulin_include))] -impl<T: Debug + ?Sized, Key: Keyable, R: RawRwLock> Debug for RwLockReadGuard<'_, '_, T, Key, R> { +impl<T: Debug + ?Sized, R: RawRwLock> Debug for RwLockReadGuard<'_, T, R> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { Debug::fmt(&**self, f) } } -impl<T: Display + ?Sized, Key: Keyable, R: RawRwLock> Display - for RwLockReadGuard<'_, '_, T, Key, R> -{ +impl<T: Display + ?Sized, R: RawRwLock> Display for RwLockReadGuard<'_, T, R> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { Display::fmt(&**self, f) } } -impl<T: ?Sized, Key: Keyable, R: RawRwLock> Deref for RwLockReadGuard<'_, '_, T, Key, R> { +impl<T: ?Sized, R: RawRwLock> Deref for RwLockReadGuard<'_, T, R> { type Target = T; fn deref(&self) -> &Self::Target { @@ -153,21 +99,20 @@ impl<T: ?Sized, Key: Keyable, R: RawRwLock> Deref for RwLockReadGuard<'_, '_, T, } } -impl<T: ?Sized, Key: Keyable, R: RawRwLock> AsRef<T> for RwLockReadGuard<'_, '_, T, Key, R> { +impl<T: ?Sized, R: RawRwLock> AsRef<T> for RwLockReadGuard<'_, T, R> { fn as_ref(&self) -> &T { self } } -impl<'a, T: ?Sized, Key: Keyable, R: RawRwLock> RwLockReadGuard<'a, '_, T, Key, R> { +impl<'a, T: ?Sized, R: RawRwLock> RwLockReadGuard<'a, T, R> { /// Create a guard to the given mutex. Undefined if multiple guards to the /// same mutex exist at once. #[must_use] - pub(super) unsafe fn new(rwlock: &'a RwLock<T, R>, thread_key: Key) -> Self { + pub(super) unsafe fn new(rwlock: &'a RwLock<T, R>, thread_key: ThreadKey) -> Self { Self { rwlock: RwLockReadRef(rwlock, PhantomData), thread_key, - _phantom: PhantomData, } } } diff --git a/src/rwlock/read_lock.rs b/src/rwlock/read_lock.rs index 5dd83a7..05b184a 100644 --- a/src/rwlock/read_lock.rs +++ b/src/rwlock/read_lock.rs @@ -2,8 +2,8 @@ use std::fmt::Debug; use lock_api::RawRwLock; -use crate::key::Keyable; use crate::lockable::{Lockable, RawLock, Sharable}; +use crate::ThreadKey; use super::{ReadLock, RwLock, RwLockReadGuard, RwLockReadRef}; @@ -13,6 +13,11 @@ unsafe impl<T: Send, R: RawRwLock + Send + Sync> Lockable for ReadLock<'_, T, R> where Self: 'g; + type DataMut<'a> + = &'a T + where + Self: 'a; + fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn RawLock>) { ptrs.push(self.as_ref()); } @@ -20,6 +25,10 @@ unsafe impl<T: Send, R: RawRwLock + Send + Sync> Lockable for ReadLock<'_, T, R> unsafe fn guard(&self) -> Self::Guard<'_> { RwLockReadRef::new(self.as_ref()) } + + unsafe fn data_mut(&self) -> Self::DataMut<'_> { + self.0.data_ref() + } } unsafe impl<T: Send, R: RawRwLock + Send + Sync> Sharable for ReadLock<'_, T, R> { @@ -28,9 +37,18 @@ unsafe impl<T: Send, R: RawRwLock + Send + Sync> Sharable for ReadLock<'_, T, R> where Self: 'g; + type DataRef<'a> + = &'a T + where + Self: 'a; + unsafe fn read_guard(&self) -> Self::Guard<'_> { RwLockReadRef::new(self.as_ref()) } + + unsafe fn data_ref(&self) -> Self::DataRef<'_> { + self.0.data_ref() + } } #[mutants::skip] @@ -117,10 +135,8 @@ impl<T: ?Sized, R: RawRwLock> ReadLock<'_, T, R> { /// ``` /// /// [`ThreadKey`]: `crate::ThreadKey` - pub fn lock<'s, 'key: 's, Key: Keyable + 'key>( - &'s self, - key: Key, - ) -> RwLockReadGuard<'s, 'key, T, Key, R> { + #[must_use] + pub fn lock(&self, key: ThreadKey) -> RwLockReadGuard<'_, T, R> { self.0.read(key) } @@ -155,10 +171,7 @@ impl<T: ?Sized, R: RawRwLock> ReadLock<'_, T, R> { /// Err(_) => unreachable!(), /// }; /// ``` - pub fn try_lock<'s, 'key: 's, Key: Keyable + 'key>( - &'s self, - key: Key, - ) -> Result<RwLockReadGuard<'s, 'key, T, Key, R>, Key> { + pub fn try_lock(&self, key: ThreadKey) -> Result<RwLockReadGuard<'_, T, R>, ThreadKey> { self.0.try_read(key) } @@ -189,7 +202,8 @@ impl<T: ?Sized, R: RawRwLock> ReadLock<'_, T, R> { /// assert_eq!(*guard, 0); /// let key = ReadLock::unlock(guard); /// ``` - pub fn unlock<'key, Key: Keyable + 'key>(guard: RwLockReadGuard<'_, 'key, T, Key, R>) -> Key { + #[must_use] + pub fn unlock(guard: RwLockReadGuard<'_, T, R>) -> ThreadKey { RwLock::unlock_read(guard) } } diff --git a/src/rwlock/rwlock.rs b/src/rwlock/rwlock.rs index 038e6c7..905ecf8 100644 --- a/src/rwlock/rwlock.rs +++ b/src/rwlock/rwlock.rs @@ -6,10 +6,10 @@ use std::panic::AssertUnwindSafe; use lock_api::RawRwLock; use crate::handle_unwind::handle_unwind; -use crate::key::Keyable; use crate::lockable::{ Lockable, LockableGetMut, LockableIntoInner, OwnedLockable, RawLock, Sharable, }; +use crate::{Keyable, ThreadKey}; use super::{PoisonFlag, RwLock, RwLockReadGuard, RwLockReadRef, RwLockWriteGuard, RwLockWriteRef}; @@ -79,6 +79,11 @@ unsafe impl<T: Send, R: RawRwLock + Send + Sync> Lockable for RwLock<T, R> { where Self: 'g; + type DataMut<'a> + = &'a mut T + where + Self: 'a; + fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn RawLock>) { ptrs.push(self); } @@ -86,6 +91,10 @@ unsafe impl<T: Send, R: RawRwLock + Send + Sync> Lockable for RwLock<T, R> { unsafe fn guard(&self) -> Self::Guard<'_> { RwLockWriteRef::new(self) } + + unsafe fn data_mut(&self) -> Self::DataMut<'_> { + self.data.get().as_mut().unwrap_unchecked() + } } unsafe impl<T: Send, R: RawRwLock + Send + Sync> Sharable for RwLock<T, R> { @@ -94,9 +103,18 @@ unsafe impl<T: Send, R: RawRwLock + Send + Sync> Sharable for RwLock<T, R> { where Self: 'g; + type DataRef<'a> + = &'a T + where + Self: 'a; + unsafe fn read_guard(&self) -> Self::ReadGuard<'_> { RwLockReadRef::new(self) } + + unsafe fn data_ref(&self) -> Self::DataRef<'_> { + self.data.get().as_ref().unwrap_unchecked() + } } unsafe impl<T: Send, R: RawRwLock + Send + Sync> OwnedLockable for RwLock<T, R> {} @@ -230,6 +248,86 @@ impl<T: ?Sized, R> RwLock<T, R> { } impl<T: ?Sized, R: RawRwLock> RwLock<T, R> { + pub fn scoped_read<Ret>(&self, key: impl Keyable, f: impl Fn(&T) -> Ret) -> Ret { + unsafe { + // safety: we have the thread key + self.raw_read(); + + // safety: the rwlock was just locked + let r = f(self.data.get().as_ref().unwrap_unchecked()); + + // safety: the rwlock is already locked + self.raw_unlock_read(); + + drop(key); // ensure the key stays valid for long enough + + r + } + } + + pub fn scoped_try_read<Key: Keyable, Ret>( + &self, + key: Key, + f: impl Fn(&T) -> Ret, + ) -> Result<Ret, Key> { + unsafe { + // safety: we have the thread key + if !self.raw_try_read() { + return Err(key); + } + + // safety: the rwlock was just locked + let r = f(self.data.get().as_ref().unwrap_unchecked()); + + // safety: the rwlock is already locked + self.raw_unlock_read(); + + drop(key); // ensure the key stays valid for long enough + + Ok(r) + } + } + + pub fn scoped_write<Ret>(&self, key: impl Keyable, f: impl Fn(&mut T) -> Ret) -> Ret { + unsafe { + // safety: we have the thread key + self.raw_lock(); + + // safety: we just locked the rwlock + let r = f(self.data.get().as_mut().unwrap_unchecked()); + + // safety: the rwlock is already locked + self.raw_unlock(); + + drop(key); // ensure the key stays valid for long enough + + r + } + } + + pub fn scoped_try_write<Key: Keyable, Ret>( + &self, + key: Key, + f: impl Fn(&mut T) -> Ret, + ) -> Result<Ret, Key> { + unsafe { + // safety: we have the thread key + if !self.raw_try_lock() { + return Err(key); + } + + // safety: the rwlock was just locked + let r = f(self.data.get().as_mut().unwrap_unchecked()); + + // safety: the rwlock is already locked + self.raw_unlock(); + + drop(key); // ensure the key stays valid for long enough + + Ok(r) + } + } + /// Locks this `RwLock` with shared read access, blocking the current /// thread until it can be acquired. /// @@ -264,10 +362,7 @@ impl<T: ?Sized, R: RawRwLock> RwLock<T, R> { /// ``` /// /// [`ThreadKey`]: `crate::ThreadKey` - pub fn read<'s, 'key: 's, Key: Keyable>( - &'s self, - key: Key, - ) -> RwLockReadGuard<'s, 'key, T, Key, R> { + pub fn read(&self, key: ThreadKey) -> RwLockReadGuard<'_, T, R> { unsafe { self.raw_read(); @@ -305,10 +400,7 @@ impl<T: ?Sized, R: RawRwLock> RwLock<T, R> { /// Err(_) => unreachable!(), /// }; /// ``` - pub fn try_read<'s, 'key: 's, Key: Keyable>( - &'s self, - key: Key, - ) -> Result<RwLockReadGuard<'s, 'key, T, Key, R>, Key> { + pub fn try_read(&self, key: ThreadKey) -> Result<RwLockReadGuard<'_, T, R>, ThreadKey> { unsafe { if self.raw_try_read() { // safety: the lock is locked first @@ -369,10 +461,7 @@ impl<T: ?Sized, R: RawRwLock> RwLock<T, R> { /// ``` /// /// [`ThreadKey`]: `crate::ThreadKey` - pub fn write<'s, 'key: 's, Key: Keyable>( - &'s self, - key: Key, - ) -> RwLockWriteGuard<'s, 'key, T, Key, R> { + pub fn write(&self, key: ThreadKey) -> RwLockWriteGuard<'_, T, R> { unsafe { self.raw_lock(); @@ -407,10 +496,7 @@ impl<T: ?Sized, R: RawRwLock> RwLock<T, R> { /// let n = lock.read(key); /// assert_eq!(*n, 1); /// ``` - pub fn try_write<'s, 'key: 's, Key: Keyable>( - &'s self, - key: Key, - ) -> Result<RwLockWriteGuard<'s, 'key, T, Key, R>, Key> { + pub fn try_write(&self, key: ThreadKey) -> Result<RwLockWriteGuard<'_, T, R>, ThreadKey> { unsafe { if self.raw_try_lock() { // safety: the lock is locked first @@ -445,9 +531,8 @@ impl<T: ?Sized, R: RawRwLock> RwLock<T, R> { /// assert_eq!(*guard, 0); /// let key = RwLock::unlock_read(guard); /// ``` - pub fn unlock_read<'key, Key: Keyable + 'key>( - guard: RwLockReadGuard<'_, 'key, T, Key, R>, - ) -> Key { + #[must_use] + pub fn unlock_read(guard: RwLockReadGuard<'_, T, R>) -> ThreadKey { unsafe { guard.rwlock.0.raw_unlock_read(); } @@ -473,9 +558,8 @@ impl<T: ?Sized, R: RawRwLock> RwLock<T, R> { /// *guard += 20; /// let key = RwLock::unlock_write(guard); /// ``` - pub fn unlock_write<'key, Key: Keyable + 'key>( - guard: RwLockWriteGuard<'_, 'key, T, Key, R>, - ) -> Key { + #[must_use] + pub fn unlock_write(guard: RwLockWriteGuard<'_, T, R>) -> ThreadKey { unsafe { guard.rwlock.0.raw_unlock(); } diff --git a/src/rwlock/write_guard.rs b/src/rwlock/write_guard.rs index c971260..3fabf8e 100644 --- a/src/rwlock/write_guard.rs +++ b/src/rwlock/write_guard.rs @@ -5,34 +5,14 @@ use std::ops::{Deref, DerefMut}; use lock_api::RawRwLock; -use crate::key::Keyable; use crate::lockable::RawLock; +use crate::ThreadKey; use super::{RwLock, RwLockWriteGuard, RwLockWriteRef}; // These impls make things slightly easier because now you can use // `println!("{guard}")` instead of `println!("{}", *guard)` -impl<T: PartialEq + ?Sized, R: RawRwLock> PartialEq for RwLockWriteRef<'_, T, R> { - fn eq(&self, other: &Self) -> bool { - self.deref().eq(&**other) - } -} - -impl<T: Eq + ?Sized, R: RawRwLock> Eq for RwLockWriteRef<'_, T, R> {} - -impl<T: PartialOrd + ?Sized, R: RawRwLock> PartialOrd for RwLockWriteRef<'_, T, R> { - fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { - self.deref().partial_cmp(&**other) - } -} - -impl<T: Ord + ?Sized, R: RawRwLock> Ord for RwLockWriteRef<'_, T, R> { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.deref().cmp(&**other) - } -} - #[mutants::skip] // hashing involves PRNG and is difficult to test #[cfg(not(tarpaulin_include))] impl<T: Hash + ?Sized, R: RawRwLock> Hash for RwLockWriteRef<'_, T, R> { @@ -104,41 +84,9 @@ impl<'a, T: ?Sized + 'a, R: RawRwLock> RwLockWriteRef<'a, T, R> { } } -#[mutants::skip] // it's hard to get two read guards safely -#[cfg(not(tarpaulin_include))] -impl<T: PartialEq + ?Sized, R: RawRwLock, Key: Keyable> PartialEq - for RwLockWriteGuard<'_, '_, T, Key, R> -{ - fn eq(&self, other: &Self) -> bool { - self.deref().eq(&**other) - } -} - -#[mutants::skip] // it's hard to get two read guards safely -#[cfg(not(tarpaulin_include))] -impl<T: Eq + ?Sized, R: RawRwLock, Key: Keyable> Eq for RwLockWriteGuard<'_, '_, T, Key, R> {} - -#[mutants::skip] // it's hard to get two read guards safely -#[cfg(not(tarpaulin_include))] -impl<T: PartialOrd + ?Sized, R: RawRwLock, Key: Keyable> PartialOrd - for RwLockWriteGuard<'_, '_, T, Key, R> -{ - fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { - self.deref().partial_cmp(&**other) - } -} - -#[mutants::skip] // it's hard to get two read guards safely -#[cfg(not(tarpaulin_include))] -impl<T: Ord + ?Sized, R: RawRwLock, Key: Keyable> Ord for RwLockWriteGuard<'_, '_, T, Key, R> { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.deref().cmp(&**other) - } -} - #[mutants::skip] // hashing involves PRNG and is difficult to test #[cfg(not(tarpaulin_include))] -impl<T: Hash + ?Sized, R: RawRwLock, Key: Keyable> Hash for RwLockWriteGuard<'_, '_, T, Key, R> { +impl<T: Hash + ?Sized, R: RawRwLock> Hash for RwLockWriteGuard<'_, T, R> { fn hash<H: std::hash::Hasher>(&self, state: &mut H) { self.deref().hash(state) } @@ -146,21 +94,19 @@ impl<T: Hash + ?Sized, R: RawRwLock, Key: Keyable> Hash for RwLockWriteGuard<'_, #[mutants::skip] #[cfg(not(tarpaulin_include))] -impl<T: Debug + ?Sized, Key: Keyable, R: RawRwLock> Debug for RwLockWriteGuard<'_, '_, T, Key, R> { +impl<T: Debug + ?Sized, R: RawRwLock> Debug for RwLockWriteGuard<'_, T, R> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { Debug::fmt(&**self, f) } } -impl<T: Display + ?Sized, Key: Keyable, R: RawRwLock> Display - for RwLockWriteGuard<'_, '_, T, Key, R> -{ +impl<T: Display + ?Sized, R: RawRwLock> Display for RwLockWriteGuard<'_, T, R> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { Display::fmt(&**self, f) } } -impl<T: ?Sized, Key: Keyable, R: RawRwLock> Deref for RwLockWriteGuard<'_, '_, T, Key, R> { +impl<T: ?Sized, R: RawRwLock> Deref for RwLockWriteGuard<'_, T, R> { type Target = T; fn deref(&self) -> &Self::Target { @@ -168,33 +114,32 @@ impl<T: ?Sized, Key: Keyable, R: RawRwLock> Deref for RwLockWriteGuard<'_, '_, T } } -impl<T: ?Sized, Key: Keyable, R: RawRwLock> DerefMut for RwLockWriteGuard<'_, '_, T, Key, R> { +impl<T: ?Sized, R: RawRwLock> DerefMut for RwLockWriteGuard<'_, T, R> { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.rwlock } } -impl<T: ?Sized, Key: Keyable, R: RawRwLock> AsRef<T> for RwLockWriteGuard<'_, '_, T, Key, R> { +impl<T: ?Sized, R: RawRwLock> AsRef<T> for RwLockWriteGuard<'_, T, R> { fn as_ref(&self) -> &T { self } } -impl<T: ?Sized, Key: Keyable, R: RawRwLock> AsMut<T> for RwLockWriteGuard<'_, '_, T, Key, R> { +impl<T: ?Sized, R: RawRwLock> AsMut<T> for RwLockWriteGuard<'_, T, R> { fn as_mut(&mut self) -> &mut T { self } } -impl<'a, T: ?Sized + 'a, Key: Keyable, R: RawRwLock> RwLockWriteGuard<'a, '_, T, Key, R> { +impl<'a, T: ?Sized + 'a, R: RawRwLock> RwLockWriteGuard<'a, T, R> { /// Create a guard to the given mutex. Undefined if multiple guards to the /// same mutex exist at once. #[must_use] - pub(super) unsafe fn new(rwlock: &'a RwLock<T, R>, thread_key: Key) -> Self { + pub(super) unsafe fn new(rwlock: &'a RwLock<T, R>, thread_key: ThreadKey) -> Self { Self { rwlock: RwLockWriteRef(rwlock, PhantomData), thread_key, - _phantom: PhantomData, } } } diff --git a/src/rwlock/write_lock.rs b/src/rwlock/write_lock.rs index cc96953..8a44a2d 100644 --- a/src/rwlock/write_lock.rs +++ b/src/rwlock/write_lock.rs @@ -2,8 +2,8 @@ use std::fmt::Debug; use lock_api::RawRwLock; -use crate::key::Keyable; use crate::lockable::{Lockable, RawLock}; +use crate::ThreadKey; use super::{RwLock, RwLockWriteGuard, RwLockWriteRef, WriteLock}; @@ -13,6 +13,11 @@ unsafe impl<T: Send, R: RawRwLock + Send + Sync> Lockable for WriteLock<'_, T, R where Self: 'g; + type DataMut<'a> + = &'a mut T + where + Self: 'a; + fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn RawLock>) { ptrs.push(self.as_ref()); } @@ -20,6 +25,10 @@ unsafe impl<T: Send, R: RawRwLock + Send + Sync> Lockable for WriteLock<'_, T, R unsafe fn guard(&self) -> Self::Guard<'_> { RwLockWriteRef::new(self.as_ref()) } + + unsafe fn data_mut(&self) -> Self::DataMut<'_> { + self.0.data_mut() + } } // Technically, the exclusive locks can also be shared, but there's currently @@ -108,10 +117,8 @@ impl<T: ?Sized, R: RawRwLock> WriteLock<'_, T, R> { /// ``` /// /// [`ThreadKey`]: `crate::ThreadKey` - pub fn lock<'s, 'key: 's, Key: Keyable + 'key>( - &'s self, - key: Key, - ) -> RwLockWriteGuard<'s, 'key, T, Key, R> { + #[must_use] + pub fn lock(&self, key: ThreadKey) -> RwLockWriteGuard<'_, T, R> { self.0.write(key) } @@ -145,10 +152,7 @@ impl<T: ?Sized, R: RawRwLock> WriteLock<'_, T, R> { /// Err(_) => unreachable!(), /// }; /// ``` - pub fn try_lock<'s, 'key: 's, Key: Keyable + 'key>( - &'s self, - key: Key, - ) -> Result<RwLockWriteGuard<'s, 'key, T, Key, R>, Key> { + pub fn try_lock(&self, key: ThreadKey) -> Result<RwLockWriteGuard<'_, T, R>, ThreadKey> { self.0.try_write(key) } @@ -176,7 +180,8 @@ impl<T: ?Sized, R: RawRwLock> WriteLock<'_, T, R> { /// *guard += 20; /// let key = WriteLock::unlock(guard); /// ``` - pub fn unlock<'key, Key: Keyable + 'key>(guard: RwLockWriteGuard<'_, 'key, T, Key, R>) -> Key { + #[must_use] + pub fn unlock(guard: RwLockWriteGuard<'_, T, R>) -> ThreadKey { RwLock::unlock_write(guard) } } |
