diff options
Diffstat (limited to 'src/collection/utils.rs')
| -rw-r--r-- | src/collection/utils.rs | 46 |
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()), ) } |
