diff options
| author | Mica White <botahamec@gmail.com> | 2024-12-26 11:26:39 -0500 |
|---|---|---|
| committer | Mica White <botahamec@gmail.com> | 2024-12-26 12:06:47 -0500 |
| commit | dc16634f4abdb1e830d2749e64b419740702b302 (patch) | |
| tree | eb51ba8293a1c719c7221d546185cfa7062c108c /src/rwlock | |
| parent | 096afea6f13692fddbfad0b07e5377cb2e81dd58 (diff) | |
Commenting
Diffstat (limited to 'src/rwlock')
| -rw-r--r-- | src/rwlock/read_guard.rs | 3 | ||||
| -rw-r--r-- | src/rwlock/read_lock.rs | 2 | ||||
| -rw-r--r-- | src/rwlock/rwlock.rs | 65 | ||||
| -rw-r--r-- | src/rwlock/write_guard.rs | 3 | ||||
| -rw-r--r-- | src/rwlock/write_lock.rs | 3 |
5 files changed, 47 insertions, 29 deletions
diff --git a/src/rwlock/read_guard.rs b/src/rwlock/read_guard.rs index 44b737e..8678a8e 100644 --- a/src/rwlock/read_guard.rs +++ b/src/rwlock/read_guard.rs @@ -10,6 +10,9 @@ use crate::lockable::RawLock; 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) diff --git a/src/rwlock/read_lock.rs b/src/rwlock/read_lock.rs index 34e3f5e..d719a50 100644 --- a/src/rwlock/read_lock.rs +++ b/src/rwlock/read_lock.rs @@ -22,8 +22,6 @@ unsafe impl<T: Send, R: RawRwLock + Send + Sync> Lockable for ReadLock<'_, T, R> } } -// Technically, the exclusive locks can also be shared, but there's currently -// no way to express that. I don't think I want to ever express that. unsafe impl<T: Send, R: RawRwLock + Send + Sync> Sharable for ReadLock<'_, T, R> { type ReadGuard<'g> = RwLockReadRef<'g, T, R> diff --git a/src/rwlock/rwlock.rs b/src/rwlock/rwlock.rs index 8bb170c..6432128 100644 --- a/src/rwlock/rwlock.rs +++ b/src/rwlock/rwlock.rs @@ -88,6 +88,19 @@ unsafe impl<T: Send, R: RawRwLock + Send + Sync> Lockable for RwLock<T, R> { } } +unsafe impl<T: Send, R: RawRwLock + Send + Sync> Sharable for RwLock<T, R> { + type ReadGuard<'g> + = RwLockReadRef<'g, T, R> + where + Self: 'g; + + unsafe fn read_guard(&self) -> Self::ReadGuard<'_> { + RwLockReadRef::new(self) + } +} + +unsafe impl<T: Send, R: RawRwLock + Send + Sync> OwnedLockable for RwLock<T, R> {} + impl<T: Send, R: RawRwLock + Send + Sync> LockableIntoInner for RwLock<T, R> { type Inner = T; @@ -107,19 +120,6 @@ impl<T: Send, R: RawRwLock + Send + Sync> LockableGetMut for RwLock<T, R> { } } -unsafe impl<T: Send, R: RawRwLock + Send + Sync> Sharable for RwLock<T, R> { - type ReadGuard<'g> - = RwLockReadRef<'g, T, R> - where - Self: 'g; - - unsafe fn read_guard(&self) -> Self::ReadGuard<'_> { - RwLockReadRef::new(self) - } -} - -unsafe impl<T: Send, R: RawRwLock + Send + Sync> OwnedLockable for RwLock<T, R> {} - impl<T, R: RawRwLock> RwLock<T, R> { /// Creates a new instance of an `RwLock<T>` which is unlocked. /// @@ -138,20 +138,6 @@ impl<T, R: RawRwLock> RwLock<T, R> { raw: R::INIT, } } - - /// Returns the underlying raw reader-writer lock object. - /// - /// Note that you will most likely need to import the [`RawRwLock`] trait - /// from `lock_api` to be able to call functions on the raw reader-writer - /// lock. - /// - /// # Safety - /// - /// This method is unsafe because it allows unlocking a mutex while - /// still holding a reference to a lock guard. - pub const unsafe fn raw(&self) -> &R { - &self.raw - } } impl<T: ?Sized + Debug, R: RawRwLock> Debug for RwLock<T, R> { @@ -188,6 +174,9 @@ impl<T, R: RawRwLock> From<T> for RwLock<T, R> { } } +// We don't need a `get_mut` because we don't have mutex poisoning. Hurray! +// This is safe because you can't have a mutable reference to the lock if it's +// locked. Being locked requires an immutable reference because of the guard. impl<T: ?Sized, R> AsMut<T> for RwLock<T, R> { fn as_mut(&mut self) -> &mut T { self.data.get_mut() @@ -216,6 +205,28 @@ impl<T, R> RwLock<T, R> { } } +impl<T: ?Sized, R> RwLock<T, R> { + /// Returns a mutable reference to the underlying data. + /// + /// Since this call borrows `RwLock` mutably, no actual locking is taking + /// place. The mutable borrow statically guarantees that no locks exist. + /// + /// # Examples + /// + /// ``` + /// use happylock::{ThreadKey, RwLock}; + /// + /// let key = ThreadKey::get().unwrap(); + /// let mut mutex = RwLock::new(0); + /// *mutex.get_mut() = 10; + /// assert_eq!(*mutex.read(key), 10); + /// ``` + #[must_use] + pub fn get_mut(&mut self) -> &mut T { + self.data.get_mut() + } +} + impl<T: ?Sized, R: RawRwLock> RwLock<T, R> { /// Locks this `RwLock` with shared read access, blocking the current /// thread until it can be acquired. diff --git a/src/rwlock/write_guard.rs b/src/rwlock/write_guard.rs index c22ebe1..aec3d3d 100644 --- a/src/rwlock/write_guard.rs +++ b/src/rwlock/write_guard.rs @@ -10,6 +10,9 @@ use crate::lockable::RawLock; 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) diff --git a/src/rwlock/write_lock.rs b/src/rwlock/write_lock.rs index 27fa1d2..e9be750 100644 --- a/src/rwlock/write_lock.rs +++ b/src/rwlock/write_lock.rs @@ -22,6 +22,9 @@ unsafe impl<T: Send, R: RawRwLock + Send + Sync> Lockable for WriteLock<'_, T, R } } +// Technically, the exclusive locks can also be shared, but there's currently +// no way to express that. I don't think I want to ever express that. + impl<T: ?Sized + Debug, R: RawRwLock> Debug for WriteLock<'_, T, R> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { // safety: this is just a try lock, and the value is dropped |
