summaryrefslogtreecommitdiff
path: root/src/mutex.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mutex.rs')
-rw-r--r--src/mutex.rs35
1 files changed, 24 insertions, 11 deletions
diff --git a/src/mutex.rs b/src/mutex.rs
index f395055..9298b0c 100644
--- a/src/mutex.rs
+++ b/src/mutex.rs
@@ -1,4 +1,5 @@
use std::cell::UnsafeCell;
+use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};
use lock_api::RawMutex;
@@ -71,12 +72,15 @@ impl<'a, T: ?Sized + 'a, R: RawMutex> DerefMut for MutexRef<'a, T, R> {
///
/// [`lock`]: `Mutex::lock`
/// [`try_lock`]: `Mutex::try_lock`
-pub struct MutexGuard<'a, T: ?Sized + 'a, Key: Keyable, R: RawMutex> {
+pub struct MutexGuard<'a, 'key: 'a, T: ?Sized + 'a, Key: Keyable + 'key, R: RawMutex> {
mutex: MutexRef<'a, T, R>,
- _thread_key: Key,
+ thread_key: Key,
+ _phantom: PhantomData<&'key ()>,
}
-impl<'a, T: ?Sized + 'a, Key: Keyable, R: RawMutex> Deref for MutexGuard<'a, T, Key, R> {
+impl<'a, 'key: 'a, T: ?Sized + 'a, Key: Keyable, R: RawMutex> Deref
+ for MutexGuard<'a, 'key, T, Key, R>
+{
type Target = T;
fn deref(&self) -> &Self::Target {
@@ -84,19 +88,22 @@ impl<'a, T: ?Sized + 'a, Key: Keyable, R: RawMutex> Deref for MutexGuard<'a, T,
}
}
-impl<'a, T: ?Sized + 'a, Key: Keyable, R: RawMutex> DerefMut for MutexGuard<'a, T, Key, R> {
+impl<'a, 'key: 'a, T: ?Sized + 'a, Key: Keyable, R: RawMutex> DerefMut
+ for MutexGuard<'a, 'key, T, Key, R>
+{
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.mutex
}
}
-impl<'a, T: ?Sized + 'a, Key: Keyable, R: RawMutex> MutexGuard<'a, T, Key, R> {
+impl<'a, 'key: 'a, T: ?Sized + 'a, Key: Keyable, R: RawMutex> MutexGuard<'a, 'key, T, Key, 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: Key) -> Self {
Self {
mutex: MutexRef(mutex),
- _thread_key: thread_key,
+ thread_key,
+ _phantom: PhantomData,
}
}
}
@@ -143,7 +150,10 @@ impl<T: ?Sized, R: RawMutex> Mutex<T, R> {
/// let key = ThreadKey::lock().unwrap();
/// assert_eq!(*mutex.lock(key), 10);
/// ```
- pub fn lock<'s, 'a: 's, Key: Keyable>(&'s self, key: Key) -> MutexGuard<'_, T, Key, R> {
+ pub fn lock<'s, 'a: 's, 'k: 'a, Key: Keyable>(
+ &'s self,
+ key: Key,
+ ) -> MutexGuard<'_, 'k, T, Key, R> {
self.raw.lock();
// safety: we just locked the mutex
@@ -187,10 +197,10 @@ impl<T: ?Sized, R: RawMutex> Mutex<T, R> {
/// let key = ThreadKey::lock().unwrap();
/// assert_eq!(*mutex.lock(key), 10);
/// ```
- pub fn try_lock<'s, 'a: 's, Key: Keyable>(
+ pub fn try_lock<'s, 'a: 's, 'k: 'a, Key: Keyable>(
&'s self,
key: Key,
- ) -> Option<MutexGuard<'_, T, Key, R>> {
+ ) -> Option<MutexGuard<'_, 'k, T, Key, R>> {
if self.raw.try_lock() {
// safety: we just locked the mutex
Some(unsafe { MutexGuard::new(self, key) })
@@ -231,8 +241,11 @@ impl<T: ?Sized, R: RawMutex> Mutex<T, R> {
/// let key = Mutex::unlock(guard);
/// ```
#[allow(clippy::missing_const_for_fn)]
- pub fn unlock(guard: MutexGuard<'_, T, impl Keyable, R>) {
- drop(guard);
+ pub fn unlock<'a, 'k: 'a, Key: Keyable + 'k>(guard: MutexGuard<'a, 'k, T, Key, R>) -> Key {
+ unsafe {
+ guard.mutex.0.force_unlock();
+ }
+ guard.thread_key
}
}