summaryrefslogtreecommitdiff
path: root/src/collection/utils.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/collection/utils.rs')
-rw-r--r--src/collection/utils.rs46
1 files changed, 21 insertions, 25 deletions
diff --git a/src/collection/utils.rs b/src/collection/utils.rs
index d368773..7f29037 100644
--- a/src/collection/utils.rs
+++ b/src/collection/utils.rs
@@ -1,4 +1,4 @@
-use std::cell::RefCell;
+use std::cell::Cell;
use crate::handle_unwind::handle_unwind;
use crate::lockable::RawLock;
@@ -6,31 +6,31 @@ use crate::lockable::RawLock;
/// Lock a set of locks in the given order. It's UB to call this without a `ThreadKey`
pub unsafe fn ordered_lock(locks: &[&dyn RawLock]) {
// these will be unlocked in case of a panic
- let locked = RefCell::new(Vec::with_capacity(locks.len()));
+ let locked = Cell::new(0);
handle_unwind(
|| {
for lock in locks {
lock.raw_lock();
- locked.borrow_mut().push(*lock);
+ locked.set(locked.get() + 1);
}
},
- || attempt_to_recover_locks_from_panic(&locked),
+ || attempt_to_recover_locks_from_panic(&locks[0..locked.get()]),
)
}
/// Lock a set of locks in the given order. It's UB to call this without a `ThreadKey`
pub unsafe fn ordered_read(locks: &[&dyn RawLock]) {
- let locked = RefCell::new(Vec::with_capacity(locks.len()));
+ let locked = Cell::new(0);
handle_unwind(
|| {
for lock in locks {
lock.raw_read();
- locked.borrow_mut().push(*lock);
+ locked.set(locked.get() + 1);
}
},
- || attempt_to_recover_reads_from_panic(&locked),
+ || attempt_to_recover_reads_from_panic(&locks[0..locked.get()]),
)
}
@@ -38,14 +38,14 @@ pub unsafe fn ordered_read(locks: &[&dyn RawLock]) {
/// locks contain duplicates, or if this is called by multiple threads with the
/// locks in different orders.
pub unsafe fn ordered_try_lock(locks: &[&dyn RawLock]) -> bool {
- let locked = RefCell::new(Vec::with_capacity(locks.len()));
+ let locked = Cell::new(0);
handle_unwind(
|| unsafe {
for (i, lock) in locks.iter().enumerate() {
// safety: we have the thread key
if lock.raw_try_lock() {
- locked.borrow_mut().push(*lock);
+ locked.set(locked.get() + 1);
} else {
for lock in &locks[0..i] {
// safety: this lock was already acquired
@@ -59,7 +59,7 @@ pub unsafe fn ordered_try_lock(locks: &[&dyn RawLock]) -> bool {
},
||
// safety: everything in locked is locked
- attempt_to_recover_locks_from_panic(&locked),
+ attempt_to_recover_locks_from_panic(&locks[0..locked.get()]),
)
}
@@ -67,14 +67,14 @@ pub unsafe fn ordered_try_lock(locks: &[&dyn RawLock]) -> bool {
/// is called by multiple threads with the locks in different orders.
pub unsafe fn ordered_try_read(locks: &[&dyn RawLock]) -> bool {
// these will be unlocked in case of a panic
- let locked = RefCell::new(Vec::with_capacity(locks.len()));
+ let locked = Cell::new(0);
handle_unwind(
|| unsafe {
for (i, lock) in locks.iter().enumerate() {
// safety: we have the thread key
if lock.raw_try_read() {
- locked.borrow_mut().push(*lock);
+ locked.set(locked.get() + 1);
} else {
for lock in &locks[0..i] {
// safety: this lock was already acquired
@@ -88,34 +88,30 @@ pub unsafe fn ordered_try_read(locks: &[&dyn RawLock]) -> bool {
},
||
// safety: everything in locked is locked
- attempt_to_recover_reads_from_panic(&locked),
+ attempt_to_recover_reads_from_panic(&locks[0..locked.get()]),
)
}
/// Unlocks the already locked locks in order to recover from a panic
-pub unsafe fn attempt_to_recover_locks_from_panic(locked: &RefCell<Vec<&dyn RawLock>>) {
+pub unsafe fn attempt_to_recover_locks_from_panic(locks: &[&dyn RawLock]) {
handle_unwind(
|| {
- let mut locked = locked.borrow_mut();
- while let Some(locked_lock) = locked.pop() {
- locked_lock.raw_unlock();
- }
+ // safety: the caller assumes that these are already locked
+ locks.iter().for_each(|lock| lock.raw_unlock());
},
// if we get another panic in here, we'll just have to poison what remains
- || locked.borrow().iter().for_each(|l| l.poison()),
+ || locks.iter().for_each(|l| l.poison()),
)
}
/// Unlocks the already locked locks in order to recover from a panic
-pub unsafe fn attempt_to_recover_reads_from_panic(locked: &RefCell<Vec<&dyn RawLock>>) {
+pub unsafe fn attempt_to_recover_reads_from_panic(locked: &[&dyn RawLock]) {
handle_unwind(
|| {
- let mut locked = locked.borrow_mut();
- while let Some(locked_lock) = locked.pop() {
- locked_lock.raw_unlock_read();
- }
+ // safety: the caller assumes these are already locked
+ locked.iter().for_each(|lock| lock.raw_unlock());
},
// if we get another panic in here, we'll just have to poison what remains
- || locked.borrow().iter().for_each(|l| l.poison()),
+ || locked.iter().for_each(|l| l.poison()),
)
}