From 16b477429c39f0ef7d3b813c9ea945ab8c6d65e5 Mon Sep 17 00:00:00 2001 From: Mica White Date: Sat, 9 Mar 2024 09:38:11 -0500 Subject: Add Vec as a lockable type --- src/lockable.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'src/lockable.rs') diff --git a/src/lockable.rs b/src/lockable.rs index 1aad8d9..64c0b02 100644 --- a/src/lockable.rs +++ b/src/lockable.rs @@ -13,6 +13,7 @@ mod sealed { impl Sealed for &mut T {} impl<'a, A: Lockable<'a>, B: Lockable<'a>> Sealed for (A, B) {} impl<'a, T: Lockable<'a>, const N: usize> Sealed for [T; N] {} + impl<'a, T: Lockable<'a>> Sealed for Vec {} } /// A type that may be locked and unlocked @@ -175,3 +176,35 @@ unsafe impl<'a, T: Lockable<'a>, const N: usize> Lockable<'a> for [T; N] { guard.map(T::unlock); } } + +unsafe impl<'a, T: Lockable<'a>> Lockable<'a> for Vec { + type Output = Vec; + + unsafe fn lock(&'a self) -> Self::Output { + loop { + if let Some(guard) = self.try_lock() { + return guard; + } + } + } + + unsafe fn try_lock(&'a self) -> Option { + let mut outputs = Vec::new(); + for lock in self { + if let Some(guard) = lock.try_lock() { + outputs.push(guard); + } else { + Self::unlock(outputs); + return None; + }; + } + + Some(outputs) + } + + fn unlock(guard: Self::Output) { + for guard in guard { + T::unlock(guard); + } + } +} -- cgit v1.2.3