summaryrefslogtreecommitdiff
path: root/src/lockable.rs
diff options
context:
space:
mode:
authorMica White <botahamec@outlook.com>2025-03-12 22:19:38 -0400
committerMica White <botahamec@outlook.com>2025-03-12 22:19:38 -0400
commitf347b3e7ca771f11a21d2f6e54c0d97796174d37 (patch)
tree6776aa84a0fb91f5619f9669f083e0316f0526b9 /src/lockable.rs
parent58abf5872023aca7ee6459fa3b2e067d57923ba5 (diff)
Add unwind handling for scoped locks
Diffstat (limited to 'src/lockable.rs')
-rw-r--r--src/lockable.rs55
1 files changed, 32 insertions, 23 deletions
diff --git a/src/lockable.rs b/src/lockable.rs
index 94042ea..16e3968 100644
--- a/src/lockable.rs
+++ b/src/lockable.rs
@@ -105,6 +105,9 @@ pub unsafe trait RawLock {
/// The order of the resulting list from `get_ptrs` must be deterministic. As
/// long as the value is not mutated, the references must always be in the same
/// order.
+///
+/// The list returned by `get_ptrs` must contain any lock which could possibly
+/// be referenced in another collection.
pub unsafe trait Lockable {
/// The exclusive guard that does not hold a key
type Guard<'g>
@@ -333,8 +336,6 @@ macro_rules! tuple_impls {
}
unsafe fn guard(&self) -> Self::Guard<'_> {
- // It's weird that this works
- // I don't think any other way of doing it compiles
($(self.$value.guard(),)*)
}
@@ -525,27 +526,17 @@ impl<T: LockableGetMut + 'static> LockableGetMut for Box<[T]> {
}
}
-unsafe impl<T: Sharable> Sharable for Box<[T]> {
- type ReadGuard<'g>
- = Box<[T::ReadGuard<'g>]>
- where
- Self: 'g;
-
- type DataRef<'a>
- = Box<[T::DataRef<'a>]>
- where
- Self: 'a;
-
- unsafe fn read_guard(&self) -> Self::ReadGuard<'_> {
- self.iter().map(|lock| lock.read_guard()).collect()
- }
+impl<T: LockableIntoInner + 'static> LockableIntoInner for Box<[T]> {
+ type Inner = Box<[T::Inner]>;
- unsafe fn data_ref(&self) -> Self::DataRef<'_> {
- self.iter().map(|lock| lock.data_ref()).collect()
+ fn into_inner(self) -> Self::Inner {
+ Self::into_iter(self)
+ .map(LockableIntoInner::into_inner)
+ .collect()
}
}
-unsafe impl<T: Sharable> Sharable for Vec<T> {
+unsafe impl<T: Sharable> Sharable for Box<[T]> {
type ReadGuard<'g>
= Box<[T::ReadGuard<'g>]>
where
@@ -565,8 +556,6 @@ unsafe impl<T: Sharable> Sharable for Vec<T> {
}
}
-unsafe impl<T: OwnedLockable> OwnedLockable for Box<[T]> {}
-
unsafe impl<T: Lockable> Lockable for Vec<T> {
// There's no reason why I'd ever want to extend a list of lock guards
type Guard<'g>
@@ -594,11 +583,31 @@ unsafe impl<T: Lockable> Lockable for Vec<T> {
}
}
+unsafe impl<T: Sharable> Sharable for Vec<T> {
+ type ReadGuard<'g>
+ = Box<[T::ReadGuard<'g>]>
+ where
+ Self: 'g;
+
+ type DataRef<'a>
+ = Box<[T::DataRef<'a>]>
+ where
+ Self: 'a;
+
+ unsafe fn read_guard(&self) -> Self::ReadGuard<'_> {
+ self.iter().map(|lock| lock.read_guard()).collect()
+ }
+
+ unsafe fn data_ref(&self) -> Self::DataRef<'_> {
+ self.iter().map(|lock| lock.data_ref()).collect()
+ }
+}
+
+unsafe impl<T: OwnedLockable> OwnedLockable for Box<[T]> {}
+
// I'd make a generic impl<T: Lockable, I: IntoIterator<Item=T>> Lockable for I
// but I think that'd require sealing up this trait
-// TODO: using edition 2024, impl LockableIntoInner for Box<[T]>
-
impl<T: LockableGetMut + 'static> LockableGetMut for Vec<T> {
type Inner<'a>
= Box<[T::Inner<'a>]>