From f347b3e7ca771f11a21d2f6e54c0d97796174d37 Mon Sep 17 00:00:00 2001 From: Mica White Date: Wed, 12 Mar 2025 22:19:38 -0400 Subject: Add unwind handling for scoped locks --- src/lockable.rs | 55 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 23 deletions(-) (limited to 'src/lockable.rs') 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 LockableGetMut for Box<[T]> { } } -unsafe impl 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 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 Sharable for Vec { +unsafe impl Sharable for Box<[T]> { type ReadGuard<'g> = Box<[T::ReadGuard<'g>]> where @@ -565,8 +556,6 @@ unsafe impl Sharable for Vec { } } -unsafe impl OwnedLockable for Box<[T]> {} - unsafe impl Lockable for Vec { // 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 Lockable for Vec { } } +unsafe impl Sharable for Vec { + 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 OwnedLockable for Box<[T]> {} + // I'd make a generic impl> Lockable for I // but I think that'd require sealing up this trait -// TODO: using edition 2024, impl LockableIntoInner for Box<[T]> - impl LockableGetMut for Vec { type Inner<'a> = Box<[T::Inner<'a>]> -- cgit v1.2.3