summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMica White <botahamec@outlook.com>2024-03-09 09:38:11 -0500
committerMica White <botahamec@outlook.com>2024-03-09 09:38:11 -0500
commit16b477429c39f0ef7d3b813c9ea945ab8c6d65e5 (patch)
tree6f5122c69a2874bff7a1c06c941c6c4a5eeb91df /src
parent1d1f12da8c9251668a62217620c94fc732ac9f78 (diff)
Add Vec as a lockable type
Diffstat (limited to 'src')
-rw-r--r--src/lockable.rs33
1 files changed, 33 insertions, 0 deletions
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<T: Sealed> 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<T> {}
}
/// 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<T> {
+ type Output = Vec<T::Output>;
+
+ unsafe fn lock(&'a self) -> Self::Output {
+ loop {
+ if let Some(guard) = self.try_lock() {
+ return guard;
+ }
+ }
+ }
+
+ unsafe fn try_lock(&'a self) -> Option<Self::Output> {
+ 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);
+ }
+ }
+}