From fe67aa262f1b04fb6c38683d9221c3a2fafcc35a Mon Sep 17 00:00:00 2001 From: Mica White Date: Sun, 10 Mar 2024 20:21:00 -0400 Subject: Reorganization --- src/rwlock/rwlock.rs | 163 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 src/rwlock/rwlock.rs (limited to 'src/rwlock/rwlock.rs') diff --git a/src/rwlock/rwlock.rs b/src/rwlock/rwlock.rs new file mode 100644 index 0000000..946f67e --- /dev/null +++ b/src/rwlock/rwlock.rs @@ -0,0 +1,163 @@ +use std::cell::UnsafeCell; +use std::fmt::Debug; + +use lock_api::RawRwLock; + +use crate::key::Keyable; + +use super::{RwLock, RwLockReadGuard, RwLockReadRef, RwLockWriteGuard, RwLockWriteRef}; + +impl RwLock { + #[must_use] + pub const fn new(value: T) -> Self { + Self { + value: UnsafeCell::new(value), + raw: R::INIT, + } + } +} + +impl Debug for RwLock { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&format!("RwLock<{}>", std::any::type_name::())) + } +} + +impl From for RwLock { + fn from(value: T) -> Self { + Self::new(value) + } +} + +impl AsMut for RwLock { + fn as_mut(&mut self) -> &mut T { + self.get_mut() + } +} + +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 + } + } + + pub(super) unsafe fn force_unlock_read(&self) { + self.raw.unlock_shared(); + } + + pub(super) 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 + } +} + +unsafe impl Send for RwLock {} +unsafe impl Sync for RwLock {} -- cgit v1.2.3