From 4c70d999d6ecbf634dfb84de2d1a3195ad63f9bb Mon Sep 17 00:00:00 2001 From: Bert Peters Date: Sat, 10 Jul 2021 12:07:40 +0200 Subject: [PATCH] Create type aliases for parking_lot::RwLock --- src/parkinglot.rs | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/parkinglot.rs b/src/parkinglot.rs index 2524aa3..7158623 100644 --- a/src/parkinglot.rs +++ b/src/parkinglot.rs @@ -21,6 +21,7 @@ debug_variant!( parking_lot::RawFairMutex ); debug_variant!(DebugRawMutex, TracingRawMutex, parking_lot::RawMutex); +debug_variant!(DebugRawRwLock, TracingRawRwLock, parking_lot::RawRwLock); /// Dependency tracking fair mutex. See: [`parking_lot::FairMutex`]. pub type TracingFairMutex = lock_api::Mutex; @@ -47,6 +48,10 @@ pub type DebugMutex = lock_api::Mutex; pub type DebugMutexGuard<'a, T> = lock_api::MutexGuard<'a, DebugRawMutex, T>; /// Dependency tracking reentrant mutex. See: [`parking_lot::ReentrantMutex`]. +/// +/// **Note:** due to the way dependencies are tracked, this mutex can only be acquired directly +/// after itself. Acquiring any other mutex in between introduces a dependency cycle, and will +/// therefore be rejected. pub type TracingReentrantMutex = lock_api::ReentrantMutex, parking_lot::RawThreadId, T>; /// Mutex guard for [`TracingReentrantMutex`]. @@ -67,6 +72,23 @@ pub type DebugReentrantMutex = pub type DebugReentrantMutexGuard<'a, T> = lock_api::ReentrantMutexGuard<'a, DebugRawMutex, parking_lot::RawThreadId, T>; +/// Dependency tracking RwLock. See: [`parking_lot::RwLock`]. +pub type TracingRwLock = lock_api::RwLock; +/// Read guard for [`TracingRwLock`]. +pub type TracingRwLockReadGuard<'a, T> = lock_api::RwLockReadGuard<'a, TracingRawRwLock, T>; +/// Write guard for [`TracingRwLock`]. +pub type TracingRwLockWriteGuard<'a, T> = lock_api::RwLockWriteGuard<'a, TracingRawRwLock, T>; + +/// Debug-only dependency tracking RwLock. +/// +/// If debug assertions are enabled this resolved to [`TracingRwLock`] and to +/// [`parking_lot::RwLock`] otherwise. +pub type DebugRwLock = lock_api::RwLock; +/// Read guard for [`TracingRwLock`]. +pub type DebugRwLockReadGuard<'a, T> = lock_api::RwLockReadGuard<'a, DebugRawRwLock, T>; +/// Write guard for [`TracingRwLock`]. +pub type DebugRwLockWriteGuard<'a, T> = lock_api::RwLockWriteGuard<'a, DebugRawRwLock, T>; + /// A dependency-tracking wrapper for [`parking_lot::Once`]. #[derive(Debug, Default)] pub struct TracingOnce { @@ -154,6 +176,21 @@ mod tests { } } + #[test] + fn test_rwlock_usage() { + let lock = Arc::new(TracingRwLock::new(())); + let lock2 = Arc::clone(&lock); + + let _read_lock = lock.read(); + + // Should be able to acquire lock in the background + thread::spawn(move || { + let _read_lock = lock2.read(); + }) + .join() + .unwrap(); + } + #[test] fn test_once_usage() { let once = Arc::new(TracingOnce::new());