1pub trait Lifetime<'this, ImplicitBounds: bounds::Sealed = bounds::Bounds<&'this Self>> {
5 type ExclusiveGuard;
7
8 type SharedGuard;
10}
11
12pub unsafe trait Lock: for<'this> Lifetime<'this> {
22 fn lock_exclusive(&self) -> <Self as Lifetime<'_>>::ExclusiveGuard;
28
29 fn lock_shared(&self) -> <Self as Lifetime<'_>>::SharedGuard;
35}
36
37macro_rules! impl_for_wrapper {
38 ($($t:ty),*) => { $(
39 impl<'this, L: Lock> Lifetime<'this> for $t {
40 type ExclusiveGuard = <L as Lifetime<'this>>::ExclusiveGuard;
41 type SharedGuard = <L as Lifetime<'this>>::SharedGuard;
42 }
43 unsafe impl<L: Lock> Lock for $t {
44 fn lock_exclusive(&self) -> <Self as Lifetime<'_>>::ExclusiveGuard {
45 (**self).lock_exclusive()
46 }
47 fn lock_shared(&self) -> <Self as Lifetime<'_>>::SharedGuard {
48 (**self).lock_shared()
49 }
50 }
51 )* };
52}
53impl_for_wrapper!(&L, &mut L);
54
55#[cfg(feature = "alloc")]
56impl_for_wrapper!(alloc::boxed::Box<L>, alloc::rc::Rc<L>, alloc::sync::Arc<L>);
57
58pub mod local {
63 use crate::lock;
64 use crate::lock::Lock;
65 use core::cell::Cell;
66 use core::cell::UnsafeCell;
67 use core::ops::Deref;
68 use core::ops::DerefMut;
69
70 #[derive(Debug)]
75 pub struct Local<T> {
76 locked: Cell<bool>,
77 data: UnsafeCell<T>,
78 }
79
80 impl<T> Local<T> {
81 #[must_use]
83 pub const fn new(value: T) -> Self {
84 Self {
85 locked: Cell::new(false),
86 data: UnsafeCell::new(value),
87 }
88 }
89
90 #[must_use]
92 pub fn get_mut(&mut self) -> &mut T {
93 self.data.get_mut()
94 }
95
96 #[must_use]
98 pub fn into_inner(self) -> T {
99 self.data.into_inner()
100 }
101
102 #[must_use]
104 pub fn is_locked(&self) -> bool {
105 self.locked.get()
106 }
107 }
108
109 impl<T: Default> Default for Local<T> {
110 fn default() -> Self {
111 Self::new(T::default())
112 }
113 }
114
115 impl<T> From<T> for Local<T> {
116 fn from(value: T) -> Self {
117 Self::new(value)
118 }
119 }
120
121 impl<'this, T> lock::Lifetime<'this> for Local<T> {
122 type ExclusiveGuard = Guard<'this, T>;
123 type SharedGuard = Guard<'this, T>;
124 }
125 unsafe impl<T> Lock for Local<T> {
126 #[track_caller]
127 fn lock_exclusive(&self) -> <Self as lock::Lifetime<'_>>::ExclusiveGuard {
128 assert!(!self.is_locked(), "Attempted to recursively lock `Local`");
129 self.locked.set(true);
130 Guard { lock: self }
131 }
132 fn lock_shared(&self) -> <Self as lock::Lifetime<'_>>::SharedGuard {
133 self.lock_exclusive()
134 }
135 }
136
137 #[derive(Debug)]
142 pub struct Guard<'lock, T> {
143 lock: &'lock Local<T>,
144 }
145
146 impl<T> Deref for Guard<'_, T> {
147 type Target = T;
148 fn deref(&self) -> &Self::Target {
149 unsafe { &*self.lock.data.get() }
150 }
151 }
152 impl<T> DerefMut for Guard<'_, T> {
153 fn deref_mut(&mut self) -> &mut Self::Target {
154 unsafe { &mut *self.lock.data.get() }
155 }
156 }
157
158 impl<T> Drop for Guard<'_, T> {
159 fn drop(&mut self) {
160 debug_assert!(self.lock.is_locked());
161 self.lock.locked.set(false);
162 }
163 }
164}
165#[doc(no_inline)]
166pub use local::Local;
167
168mod ref_cell {
169 use crate::lock;
170 use crate::lock::Lock;
171 use core::cell;
172 use core::cell::RefCell;
173
174 impl<'this, T> lock::Lifetime<'this> for RefCell<T> {
175 type ExclusiveGuard = cell::RefMut<'this, T>;
176 type SharedGuard = cell::Ref<'this, T>;
177 }
178 unsafe impl<T> Lock for RefCell<T> {
179 fn lock_exclusive(&self) -> <Self as lock::Lifetime<'_>>::ExclusiveGuard {
180 self.borrow_mut()
181 }
182 fn lock_shared(&self) -> <Self as lock::Lifetime<'_>>::SharedGuard {
183 self.borrow()
184 }
185 }
186}
187
188#[cfg(feature = "std")]
189mod std {
190 use crate::lock;
191 use crate::lock::Lock;
192 use std::sync::Mutex;
193 use std::sync::MutexGuard;
194 use std::sync::RwLock;
195 use std::sync::RwLockReadGuard;
196 use std::sync::RwLockWriteGuard;
197
198 #[cfg_attr(doc_nightly, doc(cfg(feature = "std")))]
199 impl<'this, T> lock::Lifetime<'this> for Mutex<T> {
200 type ExclusiveGuard = MutexGuard<'this, T>;
201 type SharedGuard = MutexGuard<'this, T>;
202 }
203 #[cfg_attr(doc_nightly, doc(cfg(feature = "std")))]
204 unsafe impl<T> Lock for Mutex<T> {
205 fn lock_exclusive(&self) -> <Self as lock::Lifetime<'_>>::ExclusiveGuard {
206 self.lock().unwrap()
207 }
208 fn lock_shared(&self) -> <Self as lock::Lifetime<'_>>::SharedGuard {
209 self.lock_exclusive()
210 }
211 }
212
213 #[cfg_attr(doc_nightly, doc(cfg(feature = "std")))]
214 impl<'this, T> lock::Lifetime<'this> for RwLock<T> {
215 type ExclusiveGuard = RwLockWriteGuard<'this, T>;
216 type SharedGuard = RwLockReadGuard<'this, T>;
217 }
218 #[cfg_attr(doc_nightly, doc(cfg(feature = "std")))]
219 unsafe impl<T> Lock for RwLock<T> {
220 fn lock_exclusive(&self) -> <Self as lock::Lifetime<'_>>::ExclusiveGuard {
221 self.write().unwrap()
222 }
223 fn lock_shared(&self) -> <Self as lock::Lifetime<'_>>::SharedGuard {
224 self.read().unwrap()
225 }
226 }
227}
228
229#[cfg(feature = "lock_api_04")]
230mod lock_api_04 {
231 use crate::lock;
232 use crate::lock::Lock;
233 use lock_api_04::Mutex;
234 use lock_api_04::MutexGuard;
235 use lock_api_04::RawMutex;
236 use lock_api_04::RawRwLock;
237 use lock_api_04::RwLock;
238 use lock_api_04::RwLockReadGuard;
239 use lock_api_04::RwLockWriteGuard;
240
241 #[cfg_attr(doc_nightly, doc(cfg(feature = "lock_api_04")))]
242 impl<'this, R: RawMutex, T> lock::Lifetime<'this> for Mutex<R, T> {
243 type ExclusiveGuard = MutexGuard<'this, R, T>;
244 type SharedGuard = MutexGuard<'this, R, T>;
245 }
246 #[cfg_attr(doc_nightly, doc(cfg(feature = "lock_api_04")))]
247 unsafe impl<R: RawMutex, T> Lock for Mutex<R, T> {
248 fn lock_exclusive(&self) -> <Self as lock::Lifetime<'_>>::ExclusiveGuard {
249 self.lock()
250 }
251 fn lock_shared(&self) -> <Self as lock::Lifetime<'_>>::SharedGuard {
252 self.lock_exclusive()
253 }
254 }
255
256 #[cfg_attr(doc_nightly, doc(cfg(feature = "lock_api_04")))]
257 impl<'this, R: RawRwLock, T> lock::Lifetime<'this> for RwLock<R, T> {
258 type ExclusiveGuard = RwLockWriteGuard<'this, R, T>;
259 type SharedGuard = RwLockReadGuard<'this, R, T>;
260 }
261 #[cfg_attr(doc_nightly, doc(cfg(feature = "lock_api_04")))]
262 unsafe impl<R: RawRwLock, T> Lock for RwLock<R, T> {
263 fn lock_exclusive(&self) -> <Self as lock::Lifetime<'_>>::ExclusiveGuard {
264 self.write()
265 }
266 fn lock_shared(&self) -> <Self as lock::Lifetime<'_>>::SharedGuard {
267 self.read()
268 }
269 }
270}
271
272#[cfg(feature = "loom_05")]
273mod loom_05 {
274 use crate::lock;
275 use crate::lock::Lock;
276 use loom_05_crate::sync::Mutex;
277 use loom_05_crate::sync::MutexGuard;
278 use loom_05_crate::sync::RwLock;
279 use loom_05_crate::sync::RwLockReadGuard;
280 use loom_05_crate::sync::RwLockWriteGuard;
281
282 #[cfg_attr(doc_nightly, doc(cfg(feature = "loom")))]
283 impl<'this, T> lock::Lifetime<'this> for Mutex<T> {
284 type ExclusiveGuard = MutexGuard<'this, T>;
285 type SharedGuard = MutexGuard<'this, T>;
286 }
287 #[cfg_attr(doc_nightly, doc(cfg(feature = "loom")))]
288 unsafe impl<T> Lock for Mutex<T> {
289 fn lock_exclusive(&self) -> <Self as lock::Lifetime<'_>>::ExclusiveGuard {
290 self.lock().unwrap()
291 }
292 fn lock_shared(&self) -> <Self as lock::Lifetime<'_>>::SharedGuard {
293 self.lock_exclusive()
294 }
295 }
296
297 #[cfg_attr(doc_nightly, doc(cfg(feature = "loom")))]
298 impl<'this, T> lock::Lifetime<'this> for RwLock<T> {
299 type ExclusiveGuard = RwLockWriteGuard<'this, T>;
300 type SharedGuard = RwLockReadGuard<'this, T>;
301 }
302 #[cfg_attr(doc_nightly, doc(cfg(feature = "loom")))]
303 unsafe impl<T> Lock for RwLock<T> {
304 fn lock_exclusive(&self) -> <Self as lock::Lifetime<'_>>::ExclusiveGuard {
305 self.write().unwrap()
306 }
307 fn lock_shared(&self) -> <Self as lock::Lifetime<'_>>::SharedGuard {
308 self.read().unwrap()
309 }
310 }
311}
312
313mod bounds {
314 #[allow(missing_debug_implementations)]
315 pub struct Bounds<T>(T);
316 pub trait Sealed {}
317 impl<T> Sealed for Bounds<T> {}
318}