summaryrefslogtreecommitdiff
path: root/src/mutex.rs
diff options
context:
space:
mode:
authorMica White <botahamec@outlook.com>2024-03-08 11:45:15 -0500
committerMica White <botahamec@outlook.com>2024-03-08 11:45:15 -0500
commit6b4951ade670acbe3cb34b2002fbcd4b4e6a7300 (patch)
treec800e9888ba649e2cff27cc1b8ae001c3632572d /src/mutex.rs
parentcff337867884fc5d9eff80c77d41e64ee53c6115 (diff)
Replace ownership with mutable access
Diffstat (limited to 'src/mutex.rs')
-rw-r--r--src/mutex.rs39
1 files changed, 15 insertions, 24 deletions
diff --git a/src/mutex.rs b/src/mutex.rs
index fa7bf36..e806fac 100644
--- a/src/mutex.rs
+++ b/src/mutex.rs
@@ -5,7 +5,7 @@ use crate::lock::Lock;
use crate::ThreadKey;
/// A spinning mutex
-pub type SpinLock<T> = Mutex<RawSpin, T>;
+pub type SpinLock<T> = Mutex<T, RawSpin>;
/// Implements a raw C-like mutex.
///
@@ -78,19 +78,16 @@ unsafe impl RawMutex for RawSpin {
///
/// Locking the mutex on a thread that already locked it is impossible, due to
/// the requirement of the [`ThreadKey`]. Therefore, this will never deadlock.
-/// When the [`MutexGuard`] is dropped, the [`ThreadKey`] can be reobtained by
-/// calling [`ThreadKey::lock`]. You can also get it by calling
-/// [`Mutex::unlock`].
///
/// [`lock`]: `Mutex::lock`
/// [`try_lock`]: `Mutex::try_lock`
-pub struct Mutex<T: ?Sized, R = RawSpin> {
+pub struct Mutex<T: ?Sized, R> {
raw: R,
value: UnsafeCell<T>,
}
/// A reference to a mutex that unlocks it when dropped
-pub struct MutexRef<'a, T: ?Sized + 'a, R: RawMutex = RawSpin>(&'a Mutex<T, R>);
+pub struct MutexRef<'a, T: ?Sized + 'a, R: RawMutex>(&'a Mutex<T, R>);
impl<'a, T: ?Sized + 'a, R: RawMutex> Drop for MutexRef<'a, T, R> {
fn drop(&mut self) {
@@ -129,7 +126,7 @@ impl<'a, T: ?Sized + 'a, R: RawMutex> DerefMut for MutexRef<'a, T, R> {
/// [`try_lock`]: `Mutex::try_lock`
pub struct MutexGuard<'a, T: ?Sized + 'a, R: RawMutex = RawSpin> {
mutex: MutexRef<'a, T, R>,
- thread_key: ThreadKey,
+ _thread_key: &'a mut ThreadKey,
}
impl<'a, T: ?Sized + 'a, R: RawMutex> Deref for MutexGuard<'a, T, R> {
@@ -149,10 +146,10 @@ impl<'a, T: ?Sized + 'a, R: RawMutex> DerefMut for MutexGuard<'a, T, R> {
impl<'a, T: ?Sized + 'a, R: RawMutex> MutexGuard<'a, T, R> {
/// Create a guard to the given mutex. Undefined if multiple guards to the
/// same mutex exist at once.
- const unsafe fn new(mutex: &'a Mutex<T, R>, thread_key: ThreadKey) -> Self {
+ unsafe fn new(mutex: &'a Mutex<T, R>, thread_key: &'a mut ThreadKey) -> Self {
Self {
mutex: MutexRef(mutex),
- thread_key,
+ _thread_key: thread_key,
}
}
}
@@ -199,16 +196,16 @@ impl<T: ?Sized, R: RawMutex> Mutex<T, R> {
/// let key = ThreadKey::lock().unwrap();
/// assert_eq!(*mutex.lock(key), 10);
/// ```
- pub fn lock(&self, key: ThreadKey) -> MutexGuard<'_, T, R> {
+ pub fn lock<'s, 'a: 's>(&'s self, key: &'a mut ThreadKey) -> MutexGuard<'_, T, R> {
self.raw.lock();
// safety: we just locked the mutex
unsafe { MutexGuard::new(self, key) }
}
- /// Lock without a [`ThreadKey`]. You must own the [`ThreadKey`] as long as
- /// the [`MutexRef`] is alive. This may cause deadlock if called multiple
- /// times without unlocking first.
+ /// Lock without a [`ThreadKey`]. You must mutually own the [`ThreadKey`] as
+ /// long as the [`MutexRef`] is alive. This may cause deadlock if called
+ /// multiple times without unlocking first.
pub(crate) unsafe fn lock_ref(&self) -> MutexRef<'_, T, R> {
self.raw.lock();
@@ -243,12 +240,12 @@ impl<T: ?Sized, R: RawMutex> Mutex<T, R> {
/// let key = ThreadKey::lock().unwrap();
/// assert_eq!(*mutex.lock(key), 10);
/// ```
- pub fn try_lock(&self, key: ThreadKey) -> Result<MutexGuard<'_, T, R>, ThreadKey> {
+ pub fn try_lock<'s, 'a: 's>(&'s self, key: &'a mut ThreadKey) -> Option<MutexGuard<'_, T, R>> {
if self.raw.try_lock() {
// safety: we just locked the mutex
- Ok(unsafe { MutexGuard::new(self, key) })
+ Some(unsafe { MutexGuard::new(self, key) })
} else {
- Err(key)
+ None
}
}
@@ -270,11 +267,6 @@ impl<T: ?Sized, R: RawMutex> Mutex<T, R> {
/// Consumes the [`MutexGuard`], and consequently unlocks its `Mutex`.
///
- /// This returns the [`ThreadKey`] that was used to lock the `Mutex`, which
- /// means that [`ThreadKey::lock`] does not need to be called, and will in
- /// fact return [`None`] if the [`ThreadKey`] returned by this function is
- /// not dropped.
- ///
/// # Examples
///
/// ```
@@ -289,9 +281,8 @@ impl<T: ?Sized, R: RawMutex> Mutex<T, R> {
/// let key = Mutex::unlock(guard);
/// ```
#[allow(clippy::missing_const_for_fn)]
- #[must_use]
- pub fn unlock(guard: MutexGuard<'_, T, R>) -> ThreadKey {
- guard.thread_key
+ pub fn unlock(guard: MutexGuard<'_, T, R>) {
+ drop(guard);
}
}