summaryrefslogtreecommitdiff
path: root/src/lockable.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lockable.rs')
-rw-r--r--src/lockable.rs235
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> {}