use std::sync::RwLockWriteGuard as StdRwLockWriteGuard;
use std::sync::Condvar as StdCondvar;
-use crate::prelude::HashMap;
+pub use std::sync::WaitTimeoutResult;
+
+use crate::prelude::*;
use super::{LockTestExt, LockHeldState};
Condvar { inner: StdCondvar::new() }
}
- pub fn wait<'a, T>(&'a self, guard: MutexGuard<'a, T>) -> LockResult<MutexGuard<'a, T>> {
+ pub fn wait_while<'a, T, F: FnMut(&mut T) -> bool>(&'a self, guard: MutexGuard<'a, T>, condition: F)
+ -> LockResult<MutexGuard<'a, T>> {
let mutex: &'a Mutex<T> = guard.mutex;
- self.inner.wait(guard.into_inner()).map(|lock| MutexGuard { mutex, lock }).map_err(|_| ())
+ self.inner.wait_while(guard.into_inner(), condition).map(|lock| MutexGuard { mutex, lock })
+ .map_err(|_| ())
}
#[allow(unused)]
- pub fn wait_timeout<'a, T>(&'a self, guard: MutexGuard<'a, T>, dur: Duration) -> LockResult<(MutexGuard<'a, T>, ())> {
+ pub fn wait_timeout_while<'a, T, F: FnMut(&mut T) -> bool>(&'a self, guard: MutexGuard<'a, T>, dur: Duration, condition: F)
+ -> LockResult<(MutexGuard<'a, T>, WaitTimeoutResult)> {
let mutex = guard.mutex;
- self.inner.wait_timeout(guard.into_inner(), dur).map(|(lock, _)| (MutexGuard { mutex, lock }, ())).map_err(|_| ())
+ self.inner.wait_timeout_while(guard.into_inner(), dur, condition).map_err(|_| ())
+ .map(|(lock, e)| (MutexGuard { mutex, lock }, e))
}
pub fn notify_all(&self) { self.inner.notify_all(); }
thread_local! {
/// We track the set of locks currently held by a reference to their `LockMetadata`
- static LOCKS_HELD: RefCell<HashMap<u64, Arc<LockMetadata>>> = RefCell::new(HashMap::new());
+ static LOCKS_HELD: RefCell<HashMap<u64, Arc<LockMetadata>>> = RefCell::new(new_hash_map());
}
static LOCK_IDX: AtomicUsize = AtomicUsize::new(0);
}
}
}
- let symbol = symbol_after_latest_debug_sync.expect("Couldn't find lock call symbol");
+ let symbol = symbol_after_latest_debug_sync.unwrap_or_else(|| {
+ panic!("Couldn't find lock call symbol in trace {:?}", backtrace);
+ });
(format!("{}:{}", symbol.filename().unwrap().display(), symbol.lineno().unwrap()), symbol.colno())
}
let lock_idx = LOCK_IDX.fetch_add(1, Ordering::Relaxed) as u64;
let res = Arc::new(LockMetadata {
- locked_before: StdMutex::new(HashMap::new()),
+ locked_before: StdMutex::new(new_hash_map()),
lock_idx,
_lock_construction_bt: backtrace,
});
{
let (lock_constr_location, lock_constr_colno) =
locate_call_symbol(&res._lock_construction_bt);
- LOCKS_INIT.call_once(|| { unsafe { LOCKS = Some(StdMutex::new(HashMap::new())); } });
+ LOCKS_INIT.call_once(|| { unsafe { LOCKS = Some(StdMutex::new(new_hash_map())); } });
let mut locks = unsafe { LOCKS.as_ref() }.unwrap().lock().unwrap();
match locks.entry(lock_constr_location) {
hash_map::Entry::Occupied(e) => {