use std::fmt::{Debug, Display}; use std::hash::Hash; use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; use lock_api::RawMutex; use crate::key::Keyable; use crate::lockable::RawLock; use super::{Mutex, MutexGuard, MutexRef}; impl PartialEq for MutexRef<'_, T, R> { fn eq(&self, other: &Self) -> bool { self.deref().eq(&**other) } } impl Eq for MutexRef<'_, T, R> {} impl PartialOrd for MutexRef<'_, T, R> { fn partial_cmp(&self, other: &Self) -> Option { self.deref().partial_cmp(&**other) } } impl Ord for MutexRef<'_, T, R> { fn cmp(&self, other: &Self) -> std::cmp::Ordering { self.deref().cmp(&**other) } } impl Hash for MutexRef<'_, T, R> { fn hash(&self, state: &mut H) { self.deref().hash(state) } } // This makes things slightly easier because now you can use // `println!("{guard}")` instead of `println!("{}", *guard)` impl Debug for MutexRef<'_, T, R> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { Debug::fmt(&**self, f) } } impl Display for MutexRef<'_, T, R> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { Display::fmt(&**self, f) } } impl Drop for MutexRef<'_, T, R> { fn drop(&mut self) { // safety: this guard is being destroyed, so the data cannot be // accessed without locking again unsafe { self.0.raw_unlock() } } } impl Deref for MutexRef<'_, T, R> { type Target = T; fn deref(&self) -> &Self::Target { // safety: this is the only type that can use `value`, and there's // a reference to this type, so there cannot be any mutable // references to this value. unsafe { &*self.0.data.get() } } } impl DerefMut for MutexRef<'_, T, R> { fn deref_mut(&mut self) -> &mut Self::Target { // safety: this is the only type that can use `value`, and we have a // mutable reference to this type, so there cannot be any other // references to this value. unsafe { &mut *self.0.data.get() } } } impl AsRef for MutexRef<'_, T, R> { fn as_ref(&self) -> &T { self } } impl AsMut for MutexRef<'_, T, R> { fn as_mut(&mut self) -> &mut T { self } } impl<'a, T: ?Sized, R: RawMutex> MutexRef<'a, T, R> { /// Creates a reference to the underlying data of a mutex without /// attempting to lock it or take ownership of the key. But it's also quite /// dangerous to drop. pub(crate) unsafe fn new(mutex: &'a Mutex) -> Self { Self(mutex, PhantomData) } } // it's kinda annoying to re-implement some of this stuff on guards // there's nothing i can do about that impl PartialEq for MutexGuard<'_, '_, T, Key, R> { fn eq(&self, other: &Self) -> bool { self.deref().eq(&**other) } } impl Eq for MutexGuard<'_, '_, T, Key, R> {} impl PartialOrd for MutexGuard<'_, '_, T, Key, R> { fn partial_cmp(&self, other: &Self) -> Option { self.deref().partial_cmp(&**other) } } impl Ord for MutexGuard<'_, '_, T, Key, R> { fn cmp(&self, other: &Self) -> std::cmp::Ordering { self.deref().cmp(&**other) } } impl Hash for MutexGuard<'_, '_, T, Key, R> { fn hash(&self, state: &mut H) { self.deref().hash(state) } } impl Debug for MutexGuard<'_, '_, T, Key, R> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { Debug::fmt(&**self, f) } } impl Display for MutexGuard<'_, '_, T, Key, R> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { Display::fmt(&**self, f) } } impl Deref for MutexGuard<'_, '_, T, Key, R> { type Target = T; fn deref(&self) -> &Self::Target { &self.mutex } } impl DerefMut for MutexGuard<'_, '_, T, Key, R> { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.mutex } } impl AsRef for MutexGuard<'_, '_, T, Key, R> { fn as_ref(&self) -> &T { self } } impl AsMut for MutexGuard<'_, '_, T, Key, R> { fn as_mut(&mut self) -> &mut T { self } } impl<'a, T: ?Sized, Key: Keyable, R: RawMutex> MutexGuard<'a, '_, T, Key, 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(mutex: &'a Mutex, thread_key: Key) -> Self { Self { mutex: MutexRef(mutex, PhantomData), thread_key, _phantom: PhantomData, } } } unsafe impl Sync for MutexRef<'_, T, R> {}