tracing_mutex/parkinglot/
tracing.rs1pub use parking_lot::OnceState;
3pub use parking_lot::RawThreadId;
4
5use crate::LazyMutexId;
6use crate::lockapi::TracingWrapper;
7
8pub type RawFairMutex = TracingWrapper<::parking_lot::RawFairMutex>;
9pub type RawMutex = TracingWrapper<::parking_lot::RawMutex>;
10pub type RawRwLock = TracingWrapper<::parking_lot::RawRwLock>;
11
12pub type FairMutex<T> = lock_api::Mutex<RawFairMutex, T>;
14pub type FairMutexGuard<'a, T> = lock_api::MutexGuard<'a, RawFairMutex, T>;
16pub type MappedFairMutexGuard<'a, T> = lock_api::MappedMutexGuard<'a, RawFairMutex, T>;
18
19pub type Mutex<T> = lock_api::Mutex<RawMutex, T>;
21pub type MutexGuard<'a, T> = lock_api::MutexGuard<'a, RawMutex, T>;
23pub type MappedMutexGuard<'a, T> = lock_api::MappedMutexGuard<'a, RawMutex, T>;
25
26pub type ReentrantMutex<T> = lock_api::ReentrantMutex<RawMutex, parking_lot::RawThreadId, T>;
32pub type ReentrantMutexGuard<'a, T> =
34 lock_api::ReentrantMutexGuard<'a, RawMutex, parking_lot::RawThreadId, T>;
35pub type MappedReentrantMutexGuard<'a, T> =
37 lock_api::MappedReentrantMutexGuard<'a, RawMutex, parking_lot::RawThreadId, T>;
38
39pub type RwLock<T> = lock_api::RwLock<RawRwLock, T>;
41pub type RwLockReadGuard<'a, T> = lock_api::RwLockReadGuard<'a, RawRwLock, T>;
43pub type RwLockUpgradableReadGuard<'a, T> = lock_api::RwLockUpgradableReadGuard<'a, RawRwLock, T>;
45pub type RwLockWriteGuard<'a, T> = lock_api::RwLockWriteGuard<'a, RawRwLock, T>;
47pub type MappedRwLockReadGuard<'a, T> = lock_api::MappedRwLockReadGuard<'a, RawRwLock, T>;
49pub type MappedRwLockWriteGuard<'a, T> = lock_api::MappedRwLockWriteGuard<'a, RawRwLock, T>;
51
52#[derive(Debug, Default)]
54pub struct Once {
55 inner: ::parking_lot::Once,
56 id: LazyMutexId,
57}
58
59impl Once {
60 pub const fn new() -> Self {
62 Self {
63 inner: ::parking_lot::Once::new(),
64 id: LazyMutexId::new(),
65 }
66 }
67
68 pub fn state(&self) -> OnceState {
70 self.inner.state()
71 }
72
73 pub fn call_once(&self, f: impl FnOnce()) {
81 self.id.with_held(|| self.inner.call_once(f));
82 }
83
84 pub fn call_once_force(&self, f: impl FnOnce(OnceState)) {
88 self.id.with_held(|| self.inner.call_once_force(f));
89 }
90}
91
92pub const fn const_fair_mutex<T>(val: T) -> FairMutex<T> {
94 FairMutex::const_new(<RawFairMutex as lock_api::RawMutex>::INIT, val)
95}
96
97pub const fn const_mutex<T>(val: T) -> Mutex<T> {
99 Mutex::const_new(<RawMutex as lock_api::RawMutex>::INIT, val)
100}
101
102pub const fn const_reentrant_mutex<T>(val: T) -> ReentrantMutex<T> {
104 ReentrantMutex::const_new(
105 <RawMutex as lock_api::RawMutex>::INIT,
106 <RawThreadId as lock_api::GetThreadId>::INIT,
107 val,
108 )
109}
110
111pub const fn const_rwlock<T>(val: T) -> RwLock<T> {
113 RwLock::const_new(<RawRwLock as lock_api::RawRwLock>::INIT, val)
114}
115
116#[cfg(test)]
117mod tests {
118 use std::sync::Arc;
119 use std::thread;
120
121 use super::*;
122
123 #[test]
124 fn test_mutex_usage() {
125 let mutex = Arc::new(Mutex::new(()));
126 let local_lock = mutex.lock();
127 drop(local_lock);
128
129 thread::spawn(move || {
130 let _remote_lock = mutex.lock();
131 })
132 .join()
133 .unwrap();
134 }
135
136 #[test]
137 #[should_panic]
138 fn test_mutex_conflict() {
139 let mutexes = [Mutex::new(()), Mutex::new(()), Mutex::new(())];
140
141 for i in 0..3 {
142 let _first_lock = mutexes[i].lock();
143 let _second_lock = mutexes[(i + 1) % 3].lock();
144 }
145 }
146
147 #[test]
148 fn test_rwlock_usage() {
149 let lock = Arc::new(RwLock::new(()));
150 let lock2 = Arc::clone(&lock);
151
152 let _read_lock = lock.read();
153
154 thread::spawn(move || {
156 let _read_lock = lock2.read();
157 })
158 .join()
159 .unwrap();
160 }
161
162 #[test]
163 fn test_rwlock_upgradable_read_usage() {
164 let lock = RwLock::new(());
165
166 let upgradable_guard: RwLockUpgradableReadGuard<'_, _> = lock.upgradable_read();
168
169 let _write_guard: RwLockWriteGuard<'_, _> =
171 RwLockUpgradableReadGuard::upgrade(upgradable_guard);
172 }
173
174 #[test]
175 fn test_once_usage() {
176 let once = Arc::new(Once::new());
177 let once_clone = once.clone();
178
179 assert!(!once_clone.state().done());
180
181 let handle = thread::spawn(move || {
182 assert!(!once_clone.state().done());
183
184 once_clone.call_once(|| {});
185
186 assert!(once_clone.state().done());
187 });
188
189 handle.join().unwrap();
190
191 assert!(once.state().done());
192 }
193}