use std::{ cell::UnsafeCell, marker::PhantomData, ops::{Deref, DerefMut}, }; use lock_api::RawRwLock; use crate::key::Keyable; pub type SpinRwLock = RwLock>; pub type ParkingRwLock = RwLock; pub struct RwLock { raw: R, value: UnsafeCell, } pub struct ReadLock<'a, T: ?Sized, R>(pub(crate) &'a RwLock); pub struct WriteLock<'a, T: ?Sized, R>(pub(crate) &'a RwLock); pub struct RwLockReadRef<'a, T: ?Sized, R: RawRwLock>(&'a RwLock); pub struct RwLockWriteRef<'a, T: ?Sized, R: RawRwLock>(&'a RwLock); pub struct RwLockReadGuard<'a, 'key, T: ?Sized, Key: Keyable + 'key, R: RawRwLock> { rwlock: RwLockReadRef<'a, T, R>, thread_key: Key, _phantom: PhantomData<&'key ()>, } pub struct RwLockWriteGuard<'a, 'key, T: ?Sized, Key: Keyable + 'key, R: RawRwLock> { rwlock: RwLockWriteRef<'a, T, R>, thread_key: Key, _phantom: PhantomData<&'key ()>, } impl<'a, T: ?Sized + 'a, R: RawRwLock> Deref for RwLockReadRef<'a, 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.value.get() } } } impl<'a, T: ?Sized + 'a, R: RawRwLock> Drop for RwLockReadRef<'a, T, R> { fn drop(&mut self) { // safety: this guard is being destroyed, so the data cannot be // accessed without locking again unsafe { self.0.force_unlock_read() } } } impl<'a, T: ?Sized + 'a, R: RawRwLock> Deref for RwLockWriteRef<'a, 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.value.get() } } } impl<'a, T: ?Sized + 'a, R: RawRwLock> DerefMut for RwLockWriteRef<'a, 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.value.get() } } } impl<'a, T: ?Sized + 'a, R: RawRwLock> Drop for RwLockWriteRef<'a, T, R> { fn drop(&mut self) { // safety: this guard is being destroyed, so the data cannot be // accessed without locking again unsafe { self.0.force_unlock_write() } } } impl<'a, 'key: 'a, T: ?Sized + 'a, Key: Keyable, R: RawRwLock> Deref for RwLockReadGuard<'a, 'key, T, Key, R> { type Target = T; fn deref(&self) -> &Self::Target { &self.rwlock } } impl<'a, 'key: 'a, T: ?Sized + 'a, Key: Keyable, R: RawRwLock> Deref for RwLockWriteGuard<'a, 'key, T, Key, R> { type Target = T; fn deref(&self) -> &Self::Target { &self.rwlock } } impl<'a, 'key: 'a, T: ?Sized + 'a, Key: Keyable, R: RawRwLock> DerefMut for RwLockWriteGuard<'a, 'key, T, Key, R> { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.rwlock } } impl<'a, 'key: 'a, T: ?Sized + 'a, Key: Keyable, R: RawRwLock> RwLockReadGuard<'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(rwlock: &'a RwLock, thread_key: Key) -> Self { Self { rwlock: RwLockReadRef(rwlock), thread_key, _phantom: PhantomData, } } } impl<'a, 'key: 'a, T: ?Sized + 'a, Key: Keyable, R: RawRwLock> RwLockWriteGuard<'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(rwlock: &'a RwLock, thread_key: Key) -> Self { Self { rwlock: RwLockWriteRef(rwlock), thread_key, _phantom: PhantomData, } } } impl RwLock { pub const fn new(value: T) -> Self { Self { value: UnsafeCell::new(value), raw: R::INIT, } } } impl RwLock { pub fn into_inner(self) -> T { self.value.into_inner() } } impl RwLock { pub fn get_mut(&mut self) -> &mut T { self.value.get_mut() } } impl RwLock { pub fn read<'s, 'key: 's, Key: Keyable>( &'s self, key: Key, ) -> RwLockReadGuard<'_, 'key, T, Key, R> { unsafe { self.raw.lock_shared(); // safety: the lock is locked first RwLockReadGuard::new(self, key) } } pub(crate) unsafe fn read_no_key(&self) -> RwLockReadRef<'_, T, R> { self.raw.lock_shared(); // safety: the lock is locked first RwLockReadRef(self) } pub fn try_read<'s, 'key: 's, Key: Keyable>( &'s self, key: Key, ) -> Option> { unsafe { if self.raw.try_lock_shared() { // safety: the lock is locked first Some(RwLockReadGuard::new(self, key)) } else { None } } } pub(crate) unsafe fn try_read_no_key(&self) -> Option> { if self.raw.try_lock_shared() { // safety: the lock is locked first Some(RwLockReadRef(self)) } else { None } } pub fn write<'s, 'key: 's, Key: Keyable>( &'s self, key: Key, ) -> RwLockWriteGuard<'_, 'key, T, Key, R> { unsafe { self.raw.lock_exclusive(); // safety: the lock is locked first RwLockWriteGuard::new(self, key) } } pub(crate) unsafe fn write_no_key(&self) -> RwLockWriteRef<'_, T, R> { self.raw.lock_exclusive(); // safety: the lock is locked first RwLockWriteRef(self) } pub fn try_write<'s, 'key: 's, Key: Keyable>( &'s self, key: Key, ) -> Option> { unsafe { if self.raw.try_lock_exclusive() { // safety: the lock is locked first Some(RwLockWriteGuard::new(self, key)) } else { None } } } pub(crate) unsafe fn try_write_no_key(&self) -> Option> { if self.raw.try_lock_exclusive() { // safety: the lock is locked first Some(RwLockWriteRef(self)) } else { None } } unsafe fn force_unlock_read(&self) { self.raw.unlock_shared(); } unsafe fn force_unlock_write(&self) { self.raw.unlock_exclusive(); } pub fn unlock_read<'key, Key: Keyable + 'key>( guard: RwLockReadGuard<'_, 'key, T, Key, R>, ) -> Key { unsafe { guard.rwlock.0.force_unlock_read(); } guard.thread_key } pub fn unlock_write<'key, Key: Keyable + 'key>( guard: RwLockWriteGuard<'_, 'key, T, Key, R>, ) -> Key { unsafe { guard.rwlock.0.force_unlock_write(); } guard.thread_key } } impl<'a, T, R> ReadLock<'a, T, R> { pub const fn new(rwlock: &'a RwLock) -> Self { Self(rwlock) } } impl<'a, T: ?Sized, R: RawRwLock> ReadLock<'a, T, R> { pub fn lock<'s, 'key: 's, Key: Keyable + 'key>( &'s self, key: Key, ) -> RwLockReadGuard<'_, 'key, T, Key, R> { self.0.read(key) } pub(crate) unsafe fn lock_no_key(&self) -> RwLockReadRef<'_, T, R> { self.0.read_no_key() } pub fn try_lock<'s, 'key: 's, Key: Keyable + 'key>( &'s self, key: Key, ) -> Option> { self.0.try_read(key) } pub(crate) unsafe fn try_lock_no_key(&self) -> Option> { self.0.try_read_no_key() } pub fn unlock<'key, Key: Keyable + 'key>(guard: RwLockReadGuard<'_, 'key, T, Key, R>) -> Key { RwLock::unlock_read(guard) } } impl<'a, T, R> WriteLock<'a, T, R> { pub const fn new(rwlock: &'a RwLock) -> Self { Self(rwlock) } } impl<'a, T: ?Sized, R: RawRwLock> WriteLock<'a, T, R> { pub fn lock<'s, 'key: 's, Key: Keyable + 'key>( &'s self, key: Key, ) -> RwLockWriteGuard<'_, 'key, T, Key, R> { self.0.write(key) } pub(crate) unsafe fn lock_no_key(&self) -> RwLockWriteRef<'_, T, R> { self.0.write_no_key() } pub fn try_lock<'s, 'key: 's, Key: Keyable + 'key>( &'s self, key: Key, ) -> Option> { self.0.try_write(key) } pub(crate) unsafe fn try_lock_no_key(&self) -> Option> { self.0.try_write_no_key() } pub fn unlock<'key, Key: Keyable + 'key>(guard: RwLockWriteGuard<'_, 'key, T, Key, R>) -> Key { RwLock::unlock_write(guard) } }