diff options
| author | Botahamec <botahamec@outlook.com> | 2024-05-21 19:17:11 -0400 |
|---|---|---|
| committer | Botahamec <botahamec@outlook.com> | 2024-05-21 19:17:11 -0400 |
| commit | 86610b631c20832d160c1a38181080232a05b508 (patch) | |
| tree | d10eaefdf7ecaa6add29c87ed4be77e231b8bfd1 /src/lockable.rs | |
| parent | cf49f2900fe3c7abd1bbadacfdc745d6b5bbc235 (diff) | |
Sharable API
Diffstat (limited to 'src/lockable.rs')
| -rw-r--r-- | src/lockable.rs | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/src/lockable.rs b/src/lockable.rs index 9b3a4e4..23aeb4c 100644 --- a/src/lockable.rs +++ b/src/lockable.rs @@ -45,6 +45,12 @@ pub unsafe trait Lock: Send + Sync { /// /// It is undefined behavior to use this if the lock is not acquired unsafe fn unlock(&self); + + unsafe fn read(&self); + + unsafe fn try_read(&self) -> bool; + + unsafe fn unlock_read(&self); } pub unsafe trait Lockable { @@ -53,12 +59,21 @@ pub unsafe trait Lockable { where Self: 'g; + type ReadGuard<'g> + where + Self: 'g; + fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>); #[must_use] unsafe fn guard(&self) -> Self::Guard<'_>; + + #[must_use] + unsafe fn read_guard(&self) -> Self::ReadGuard<'_>; } +pub unsafe trait Sharable: Lockable {} + /// A type that may be locked and unlocked, and is known to be the only valid /// instance of the lock. /// @@ -80,6 +95,18 @@ unsafe impl<T: Send, R: RawMutex + Send + Sync> Lock for Mutex<T, R> { unsafe fn unlock(&self) { self.raw().unlock() } + + unsafe fn read(&self) { + self.raw().lock() + } + + unsafe fn try_read(&self) -> bool { + self.raw().try_lock() + } + + unsafe fn unlock_read(&self) { + self.raw().unlock() + } } unsafe impl<T: Send, R: RawRwLock + Send + Sync> Lock for RwLock<T, R> { @@ -94,10 +121,23 @@ unsafe impl<T: Send, R: RawRwLock + Send + Sync> Lock for RwLock<T, R> { unsafe fn unlock(&self) { self.raw().unlock_exclusive() } + + unsafe fn read(&self) { + self.raw().lock_shared() + } + + unsafe fn try_read(&self) -> bool { + self.raw().try_lock_shared() + } + + unsafe fn unlock_read(&self) { + self.raw().unlock_shared() + } } unsafe impl<T: Send, R: RawMutex + Send + Sync> Lockable for Mutex<T, R> { type Guard<'g> = MutexRef<'g, T, R> where Self: 'g; + type ReadGuard<'g> = MutexRef<'g, T, R> where Self: 'g; fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) { ptrs.push(self); @@ -106,11 +146,17 @@ unsafe impl<T: Send, R: RawMutex + Send + Sync> Lockable for Mutex<T, R> { unsafe fn guard(&self) -> Self::Guard<'_> { MutexRef::new(self) } + + unsafe fn read_guard(&self) -> Self::ReadGuard<'_> { + MutexRef::new(self) + } } unsafe impl<T: Send, R: RawRwLock + Send + Sync> Lockable for RwLock<T, R> { type Guard<'g> = RwLockWriteRef<'g, T, R> where Self: 'g; + type ReadGuard<'g> = RwLockReadRef<'g, T, R> where Self: 'g; + fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) { ptrs.push(self); } @@ -118,8 +164,14 @@ unsafe impl<T: Send, R: RawRwLock + Send + Sync> Lockable for RwLock<T, R> { unsafe fn guard(&self) -> Self::Guard<'_> { RwLockWriteRef::new(self) } + + unsafe fn read_guard(&self) -> Self::ReadGuard<'_> { + RwLockReadRef::new(self) + } } +unsafe impl<T: Send, R: RawRwLock + Send + Sync> Sharable for RwLock<T, R> {} + unsafe impl<T: Send, R: RawMutex + Send + Sync> OwnedLockable for Mutex<T, R> {} unsafe impl<T: Send, R: RawRwLock + Send + Sync> OwnedLockable for RwLock<T, R> {} @@ -127,6 +179,8 @@ unsafe impl<T: Send, R: RawRwLock + Send + Sync> OwnedLockable for RwLock<T, R> unsafe impl<'l, T: Send, R: RawRwLock + Send + Sync> Lockable for ReadLock<'l, T, R> { type Guard<'g> = RwLockReadRef<'g, T, R> where Self: 'g; + type ReadGuard<'g> = RwLockReadRef<'g, T, R> where Self: 'g; + fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) { ptrs.push(self.as_ref()); } @@ -134,11 +188,17 @@ unsafe impl<'l, T: Send, R: RawRwLock + Send + Sync> Lockable for ReadLock<'l, T unsafe fn guard(&self) -> Self::Guard<'_> { RwLockReadRef::new(self.as_ref()) } + + unsafe fn read_guard(&self) -> Self::Guard<'_> { + RwLockReadRef::new(self.as_ref()) + } } unsafe impl<'l, T: Send, R: RawRwLock + Send + Sync> Lockable for WriteLock<'l, T, R> { type Guard<'g> = RwLockWriteRef<'g, T, R> where Self: 'g; + type ReadGuard<'g> = RwLockWriteRef<'g, T, R> where Self: 'g; + fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) { ptrs.push(self.as_ref()); } @@ -146,11 +206,19 @@ unsafe impl<'l, T: Send, R: RawRwLock + Send + Sync> Lockable for WriteLock<'l, unsafe fn guard(&self) -> Self::Guard<'_> { RwLockWriteRef::new(self.as_ref()) } + + unsafe fn read_guard(&self) -> Self::Guard<'_> { + RwLockWriteRef::new(self.as_ref()) + } } +unsafe impl<'l, T: Send, R: RawRwLock + Send + Sync> Sharable for ReadLock<'l, T, R> {} + unsafe impl<T: Lockable> Lockable for &T { type Guard<'g> = T::Guard<'g> where Self: 'g; + type ReadGuard<'g> = T::ReadGuard<'g> where Self: 'g; + fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) { (*self).get_ptrs(ptrs); } @@ -158,11 +226,17 @@ unsafe impl<T: Lockable> Lockable for &T { unsafe fn guard(&self) -> Self::Guard<'_> { (*self).guard() } + + unsafe fn read_guard(&self) -> Self::ReadGuard<'_> { + (*self).read_guard() + } } unsafe impl<T: Lockable> Lockable for &mut T { type Guard<'g> = T::Guard<'g> where Self: 'g; + type ReadGuard<'g> = T::ReadGuard<'g> where Self: 'g; + fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) { (**self).get_ptrs(ptrs) } @@ -170,6 +244,10 @@ unsafe impl<T: Lockable> Lockable for &mut T { unsafe fn guard(&self) -> Self::Guard<'_> { (**self).guard() } + + unsafe fn read_guard(&self) -> Self::ReadGuard<'_> { + (**self).read_guard() + } } unsafe impl<T: OwnedLockable> OwnedLockable for &mut T {} @@ -177,6 +255,8 @@ unsafe impl<T: OwnedLockable> OwnedLockable for &mut T {} unsafe impl<A: Lockable> Lockable for (A,) { type Guard<'g> = (A::Guard<'g>,) where Self: 'g; + type ReadGuard<'g> = (A::ReadGuard<'g>,) where Self: 'g; + fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) { self.0.get_ptrs(ptrs); } @@ -184,11 +264,17 @@ unsafe impl<A: Lockable> Lockable for (A,) { unsafe fn guard(&self) -> Self::Guard<'_> { (self.0.guard(),) } + + unsafe fn read_guard(&self) -> Self::ReadGuard<'_> { + (self.0.read_guard(),) + } } unsafe impl<A: Lockable, B: Lockable> Lockable for (A, B) { type Guard<'g> = (A::Guard<'g>, B::Guard<'g>) where Self: 'g; + type ReadGuard<'g> = (A::ReadGuard<'g>, B::ReadGuard<'g>) where Self: 'g; + fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) { self.0.get_ptrs(ptrs); self.1.get_ptrs(ptrs); @@ -197,11 +283,17 @@ unsafe impl<A: Lockable, B: Lockable> Lockable for (A, B) { unsafe fn guard(&self) -> Self::Guard<'_> { (self.0.guard(), self.1.guard()) } + + unsafe fn read_guard(&self) -> Self::ReadGuard<'_> { + (self.0.read_guard(), self.1.read_guard()) + } } unsafe impl<A: Lockable, B: Lockable, C: Lockable> Lockable for (A, B, C) { type Guard<'g> = (A::Guard<'g>, B::Guard<'g>, C::Guard<'g>) where Self: 'g; + type ReadGuard<'g> = (A::ReadGuard<'g>, B::ReadGuard<'g>, C::ReadGuard<'g>) where Self: 'g; + fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) { self.0.get_ptrs(ptrs); self.1.get_ptrs(ptrs); @@ -211,11 +303,26 @@ unsafe impl<A: Lockable, B: Lockable, C: Lockable> Lockable for (A, B, C) { unsafe fn guard(&self) -> Self::Guard<'_> { (self.0.guard(), self.1.guard(), self.2.guard()) } + + unsafe fn read_guard(&self) -> Self::ReadGuard<'_> { + ( + self.0.read_guard(), + self.1.read_guard(), + self.2.read_guard(), + ) + } } unsafe impl<A: Lockable, B: Lockable, C: Lockable, D: Lockable> Lockable for (A, B, C, D) { type Guard<'g> = (A::Guard<'g>, B::Guard<'g>, C::Guard<'g>, D::Guard<'g>) where Self: 'g; + type ReadGuard<'g> = ( + A::ReadGuard<'g>, + B::ReadGuard<'g>, + C::ReadGuard<'g>, + D::ReadGuard<'g>, + ) where Self: 'g; + fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) { self.0.get_ptrs(ptrs); self.1.get_ptrs(ptrs); @@ -231,6 +338,15 @@ unsafe impl<A: Lockable, B: Lockable, C: Lockable, D: Lockable> Lockable for (A, self.3.guard(), ) } + + unsafe fn read_guard(&self) -> Self::ReadGuard<'_> { + ( + self.0.read_guard(), + self.1.read_guard(), + self.2.read_guard(), + self.3.read_guard(), + ) + } } unsafe impl<A: Lockable, B: Lockable, C: Lockable, D: Lockable, E: Lockable> Lockable @@ -244,6 +360,14 @@ unsafe impl<A: Lockable, B: Lockable, C: Lockable, D: Lockable, E: Lockable> Loc E::Guard<'g>, ) where Self: 'g; + type ReadGuard<'g> = ( + A::ReadGuard<'g>, + B::ReadGuard<'g>, + C::ReadGuard<'g>, + D::ReadGuard<'g>, + E::ReadGuard<'g>, + ) where Self: 'g; + fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) { self.0.get_ptrs(ptrs); self.1.get_ptrs(ptrs); @@ -261,6 +385,16 @@ unsafe impl<A: Lockable, B: Lockable, C: Lockable, D: Lockable, E: Lockable> Loc self.4.guard(), ) } + + unsafe fn read_guard(&self) -> Self::ReadGuard<'_> { + ( + self.0.read_guard(), + self.1.read_guard(), + self.2.read_guard(), + self.3.read_guard(), + self.4.read_guard(), + ) + } } unsafe impl<A: Lockable, B: Lockable, C: Lockable, D: Lockable, E: Lockable, F: Lockable> Lockable @@ -275,6 +409,15 @@ unsafe impl<A: Lockable, B: Lockable, C: Lockable, D: Lockable, E: Lockable, F: F::Guard<'g>, ) where Self: 'g; + type ReadGuard<'g> = ( + A::ReadGuard<'g>, + B::ReadGuard<'g>, + C::ReadGuard<'g>, + D::ReadGuard<'g>, + E::ReadGuard<'g>, + F::ReadGuard<'g>, + ) where Self: 'g; + fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) { self.0.get_ptrs(ptrs); self.1.get_ptrs(ptrs); @@ -294,6 +437,17 @@ unsafe impl<A: Lockable, B: Lockable, C: Lockable, D: Lockable, E: Lockable, F: self.5.guard(), ) } + + unsafe fn read_guard(&self) -> Self::ReadGuard<'_> { + ( + self.0.read_guard(), + self.1.read_guard(), + self.2.read_guard(), + self.3.read_guard(), + self.4.read_guard(), + self.5.read_guard(), + ) + } } unsafe impl<A: Lockable, B: Lockable, C: Lockable, D: Lockable, E: Lockable, F: Lockable, G: Lockable> @@ -309,6 +463,16 @@ unsafe impl<A: Lockable, B: Lockable, C: Lockable, D: Lockable, E: Lockable, F: G::Guard<'g>, ) where Self: 'g; + type ReadGuard<'g> = ( + A::ReadGuard<'g>, + B::ReadGuard<'g>, + C::ReadGuard<'g>, + D::ReadGuard<'g>, + E::ReadGuard<'g>, + F::ReadGuard<'g>, + G::ReadGuard<'g>, + ) where Self: 'g; + fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) { self.0.get_ptrs(ptrs); self.1.get_ptrs(ptrs); @@ -330,6 +494,40 @@ unsafe impl<A: Lockable, B: Lockable, C: Lockable, D: Lockable, E: Lockable, F: self.6.guard(), ) } + + unsafe fn read_guard(&self) -> Self::ReadGuard<'_> { + ( + self.0.read_guard(), + self.1.read_guard(), + self.2.read_guard(), + self.3.read_guard(), + self.4.read_guard(), + self.5.read_guard(), + self.6.read_guard(), + ) + } +} + +unsafe impl<A: Sharable> Sharable for (A,) {} +unsafe impl<A: Sharable, B: Sharable> Sharable for (A, B) {} + +unsafe impl<A: Sharable, B: Sharable, C: Sharable> Sharable for (A, B, C) {} + +unsafe impl<A: Sharable, B: Sharable, C: Sharable, D: Sharable> Sharable for (A, B, C, D) {} + +unsafe impl<A: Sharable, B: Sharable, C: Sharable, D: Sharable, E: Sharable> Sharable + for (A, B, C, D, E) +{ +} + +unsafe impl<A: Sharable, B: Sharable, C: Sharable, D: Sharable, E: Sharable, F: Sharable> Sharable + for (A, B, C, D, E, F) +{ +} + +unsafe impl<A: Sharable, B: Sharable, C: Sharable, D: Sharable, E: Sharable, F: Sharable, G: Sharable> + Sharable for (A, B, C, D, E, F, G) +{ } unsafe impl<A: OwnedLockable> OwnedLockable for (A,) {} @@ -373,6 +571,8 @@ unsafe impl< unsafe impl<T: Lockable, const N: usize> Lockable for [T; N] { type Guard<'g> = [T::Guard<'g>; N] where Self: 'g; + type ReadGuard<'g> = [T::ReadGuard<'g>; N] where Self: 'g; + fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) { for lock in self { lock.get_ptrs(ptrs); @@ -387,11 +587,22 @@ unsafe impl<T: Lockable, const N: usize> Lockable for [T; N] { guards.map(|g| g.assume_init()) } + + unsafe fn read_guard<'g>(&'g self) -> Self::ReadGuard<'g> { + let mut guards = MaybeUninit::<[MaybeUninit<T::ReadGuard<'g>>; N]>::uninit().assume_init(); + for i in 0..N { + guards[i].write(self[i].read_guard()); + } + + guards.map(|g| g.assume_init()) + } } unsafe impl<T: Lockable> Lockable for Box<[T]> { type Guard<'g> = Box<[T::Guard<'g>]> where Self: 'g; + type ReadGuard<'g> = Box<[T::ReadGuard<'g>]> where Self: 'g; + fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) { for lock in self.iter() { lock.get_ptrs(ptrs); @@ -406,11 +617,22 @@ unsafe impl<T: Lockable> Lockable for Box<[T]> { guards.into_boxed_slice() } + + unsafe fn read_guard(&self) -> Self::ReadGuard<'_> { + let mut guards = Vec::new(); + for lock in self.iter() { + guards.push(lock.read_guard()); + } + + guards.into_boxed_slice() + } } unsafe impl<T: Lockable> Lockable for Vec<T> { type Guard<'g> = Vec<T::Guard<'g>> where Self: 'g; + type ReadGuard<'g> = Box<[T::ReadGuard<'g>]> where Self: 'g; + fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn Lock>) { for lock in self { lock.get_ptrs(ptrs); @@ -425,8 +647,21 @@ unsafe impl<T: Lockable> Lockable for Vec<T> { guards } + + unsafe fn read_guard(&self) -> Self::ReadGuard<'_> { + let mut guards = Vec::new(); + for lock in self { + guards.push(lock.read_guard()); + } + + guards.into_boxed_slice() + } } +unsafe impl<T: Sharable, const N: usize> Sharable for [T; N] {} +unsafe impl<T: Sharable> Sharable for Box<[T]> {} +unsafe impl<T: Sharable> Sharable for Vec<T> {} + unsafe impl<T: OwnedLockable, const N: usize> OwnedLockable for [T; N] {} unsafe impl<T: OwnedLockable> OwnedLockable for Box<[T]> {} unsafe impl<T: OwnedLockable> OwnedLockable for Vec<T> {} |
