summaryrefslogtreecommitdiff
path: root/src/rwlock
diff options
context:
space:
mode:
authorMica White <botahamec@gmail.com>2024-12-26 11:26:39 -0500
committerMica White <botahamec@gmail.com>2024-12-26 12:06:47 -0500
commitdc16634f4abdb1e830d2749e64b419740702b302 (patch)
treeeb51ba8293a1c719c7221d546185cfa7062c108c /src/rwlock
parent096afea6f13692fddbfad0b07e5377cb2e81dd58 (diff)
Commenting
Diffstat (limited to 'src/rwlock')
-rw-r--r--src/rwlock/read_guard.rs3
-rw-r--r--src/rwlock/read_lock.rs2
-rw-r--r--src/rwlock/rwlock.rs65
-rw-r--r--src/rwlock/write_guard.rs3
-rw-r--r--src/rwlock/write_lock.rs3
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