1 // Copyright 2018 Amanieu d'Antras
2 //
3 // Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4 // http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5 // http://opensource.org/licenses/MIT>, at your option. This file may not be
6 // copied, modified, or distributed except according to those terms.
7 
8 use core::cell::UnsafeCell;
9 use core::fmt;
10 use core::marker::PhantomData;
11 use core::mem;
12 use core::ops::{Deref, DerefMut};
13 
14 #[cfg(feature = "arc_lock")]
15 use alloc::sync::Arc;
16 #[cfg(feature = "arc_lock")]
17 use core::mem::ManuallyDrop;
18 #[cfg(feature = "arc_lock")]
19 use core::ptr;
20 
21 #[cfg(feature = "owning_ref")]
22 use owning_ref::StableAddress;
23 
24 #[cfg(feature = "serde")]
25 use serde::{Deserialize, Deserializer, Serialize, Serializer};
26 
27 /// Basic operations for a mutex.
28 ///
29 /// Types implementing this trait can be used by `Mutex` to form a safe and
30 /// fully-functioning mutex type.
31 ///
32 /// # Safety
33 ///
34 /// Implementations of this trait must ensure that the mutex is actually
35 /// exclusive: a lock can't be acquired while the mutex is already locked.
36 pub unsafe trait RawMutex {
37     /// Initial value for an unlocked mutex.
38     // A “non-constant” const item is a legacy way to supply an initialized value to downstream
39     // static items. Can hopefully be replaced with `const fn new() -> Self` at some point.
40     #[allow(clippy::declare_interior_mutable_const)]
41     const INIT: Self;
42 
43     /// Marker type which determines whether a lock guard should be `Send`. Use
44     /// one of the `GuardSend` or `GuardNoSend` helper types here.
45     type GuardMarker;
46 
47     /// Acquires this mutex, blocking the current thread until it is able to do so.
lock(&self)48     fn lock(&self);
49 
50     /// Attempts to acquire this mutex without blocking. Returns `true`
51     /// if the lock was successfully acquired and `false` otherwise.
try_lock(&self) -> bool52     fn try_lock(&self) -> bool;
53 
54     /// Unlocks this mutex.
55     ///
56     /// # Safety
57     ///
58     /// This method may only be called if the mutex is held in the current context, i.e. it must
59     /// be paired with a successful call to [`lock`], [`try_lock`], [`try_lock_for`] or [`try_lock_until`].
60     ///
61     /// [`lock`]: #tymethod.lock
62     /// [`try_lock`]: #tymethod.try_lock
63     /// [`try_lock_for`]: trait.RawMutexTimed.html#tymethod.try_lock_for
64     /// [`try_lock_until`]: trait.RawMutexTimed.html#tymethod.try_lock_until
unlock(&self)65     unsafe fn unlock(&self);
66 
67     /// Checks whether the mutex is currently locked.
68     #[inline]
is_locked(&self) -> bool69     fn is_locked(&self) -> bool {
70         let acquired_lock = self.try_lock();
71         if acquired_lock {
72             // Safety: The lock has been successfully acquired above.
73             unsafe {
74                 self.unlock();
75             }
76         }
77         !acquired_lock
78     }
79 }
80 
81 /// Additional methods for mutexes which support fair unlocking.
82 ///
83 /// Fair unlocking means that a lock is handed directly over to the next waiting
84 /// thread if there is one, without giving other threads the opportunity to
85 /// "steal" the lock in the meantime. This is typically slower than unfair
86 /// unlocking, but may be necessary in certain circumstances.
87 pub unsafe trait RawMutexFair: RawMutex {
88     /// Unlocks this mutex using a fair unlock protocol.
89     ///
90     /// # Safety
91     ///
92     /// This method may only be called if the mutex is held in the current context, see
93     /// the documentation of [`unlock`].
94     ///
95     /// [`unlock`]: trait.RawMutex.html#tymethod.unlock
unlock_fair(&self)96     unsafe fn unlock_fair(&self);
97 
98     /// Temporarily yields the mutex to a waiting thread if there is one.
99     ///
100     /// This method is functionally equivalent to calling `unlock_fair` followed
101     /// by `lock`, however it can be much more efficient in the case where there
102     /// are no waiting threads.
103     ///
104     /// # Safety
105     ///
106     /// This method may only be called if the mutex is held in the current context, see
107     /// the documentation of [`unlock`].
108     ///
109     /// [`unlock`]: trait.RawMutex.html#tymethod.unlock
bump(&self)110     unsafe fn bump(&self) {
111         self.unlock_fair();
112         self.lock();
113     }
114 }
115 
116 /// Additional methods for mutexes which support locking with timeouts.
117 ///
118 /// The `Duration` and `Instant` types are specified as associated types so that
119 /// this trait is usable even in `no_std` environments.
120 pub unsafe trait RawMutexTimed: RawMutex {
121     /// Duration type used for `try_lock_for`.
122     type Duration;
123 
124     /// Instant type used for `try_lock_until`.
125     type Instant;
126 
127     /// Attempts to acquire this lock until a timeout is reached.
try_lock_for(&self, timeout: Self::Duration) -> bool128     fn try_lock_for(&self, timeout: Self::Duration) -> bool;
129 
130     /// Attempts to acquire this lock until a timeout is reached.
try_lock_until(&self, timeout: Self::Instant) -> bool131     fn try_lock_until(&self, timeout: Self::Instant) -> bool;
132 }
133 
134 /// A mutual exclusion primitive useful for protecting shared data
135 ///
136 /// This mutex will block threads waiting for the lock to become available. The
137 /// mutex can also be statically initialized or created via a `new`
138 /// constructor. Each mutex has a type parameter which represents the data that
139 /// it is protecting. The data can only be accessed through the RAII guards
140 /// returned from `lock` and `try_lock`, which guarantees that the data is only
141 /// ever accessed when the mutex is locked.
142 pub struct Mutex<R, T: ?Sized> {
143     raw: R,
144     data: UnsafeCell<T>,
145 }
146 
147 unsafe impl<R: RawMutex + Send, T: ?Sized + Send> Send for Mutex<R, T> {}
148 unsafe impl<R: RawMutex + Sync, T: ?Sized + Send> Sync for Mutex<R, T> {}
149 
150 impl<R: RawMutex, T> Mutex<R, T> {
151     /// Creates a new mutex in an unlocked state ready for use.
152     #[cfg(has_const_fn_trait_bound)]
153     #[inline]
new(val: T) -> Mutex<R, T>154     pub const fn new(val: T) -> Mutex<R, T> {
155         Mutex {
156             raw: R::INIT,
157             data: UnsafeCell::new(val),
158         }
159     }
160 
161     /// Creates a new mutex in an unlocked state ready for use.
162     #[cfg(not(has_const_fn_trait_bound))]
163     #[inline]
new(val: T) -> Mutex<R, T>164     pub fn new(val: T) -> Mutex<R, T> {
165         Mutex {
166             raw: R::INIT,
167             data: UnsafeCell::new(val),
168         }
169     }
170 
171     /// Consumes this mutex, returning the underlying data.
172     #[inline]
into_inner(self) -> T173     pub fn into_inner(self) -> T {
174         self.data.into_inner()
175     }
176 }
177 
178 impl<R, T> Mutex<R, T> {
179     /// Creates a new mutex based on a pre-existing raw mutex.
180     ///
181     /// This allows creating a mutex in a constant context on stable Rust.
182     #[inline]
const_new(raw_mutex: R, val: T) -> Mutex<R, T>183     pub const fn const_new(raw_mutex: R, val: T) -> Mutex<R, T> {
184         Mutex {
185             raw: raw_mutex,
186             data: UnsafeCell::new(val),
187         }
188     }
189 }
190 
191 impl<R: RawMutex, T: ?Sized> Mutex<R, T> {
192     /// Creates a new `MutexGuard` without checking if the mutex is locked.
193     ///
194     /// # Safety
195     ///
196     /// This method must only be called if the thread logically holds the lock.
197     ///
198     /// Calling this function when a guard has already been produced is undefined behaviour unless
199     /// the guard was forgotten with `mem::forget`.
200     #[inline]
make_guard_unchecked(&self) -> MutexGuard<'_, R, T>201     pub unsafe fn make_guard_unchecked(&self) -> MutexGuard<'_, R, T> {
202         MutexGuard {
203             mutex: self,
204             marker: PhantomData,
205         }
206     }
207 
208     /// Acquires a mutex, blocking the current thread until it is able to do so.
209     ///
210     /// This function will block the local thread until it is available to acquire
211     /// the mutex. Upon returning, the thread is the only thread with the mutex
212     /// held. An RAII guard is returned to allow scoped unlock of the lock. When
213     /// the guard goes out of scope, the mutex will be unlocked.
214     ///
215     /// Attempts to lock a mutex in the thread which already holds the lock will
216     /// result in a deadlock.
217     #[inline]
lock(&self) -> MutexGuard<'_, R, T>218     pub fn lock(&self) -> MutexGuard<'_, R, T> {
219         self.raw.lock();
220         // SAFETY: The lock is held, as required.
221         unsafe { self.make_guard_unchecked() }
222     }
223 
224     /// Attempts to acquire this lock.
225     ///
226     /// If the lock could not be acquired at this time, then `None` is returned.
227     /// Otherwise, an RAII guard is returned. The lock will be unlocked when the
228     /// guard is dropped.
229     ///
230     /// This function does not block.
231     #[inline]
try_lock(&self) -> Option<MutexGuard<'_, R, T>>232     pub fn try_lock(&self) -> Option<MutexGuard<'_, R, T>> {
233         if self.raw.try_lock() {
234             // SAFETY: The lock is held, as required.
235             Some(unsafe { self.make_guard_unchecked() })
236         } else {
237             None
238         }
239     }
240 
241     /// Returns a mutable reference to the underlying data.
242     ///
243     /// Since this call borrows the `Mutex` mutably, no actual locking needs to
244     /// take place---the mutable borrow statically guarantees no locks exist.
245     #[inline]
get_mut(&mut self) -> &mut T246     pub fn get_mut(&mut self) -> &mut T {
247         unsafe { &mut *self.data.get() }
248     }
249 
250     /// Checks whether the mutex is currently locked.
251     #[inline]
is_locked(&self) -> bool252     pub fn is_locked(&self) -> bool {
253         self.raw.is_locked()
254     }
255 
256     /// Forcibly unlocks the mutex.
257     ///
258     /// This is useful when combined with `mem::forget` to hold a lock without
259     /// the need to maintain a `MutexGuard` object alive, for example when
260     /// dealing with FFI.
261     ///
262     /// # Safety
263     ///
264     /// This method must only be called if the current thread logically owns a
265     /// `MutexGuard` but that guard has been discarded using `mem::forget`.
266     /// Behavior is undefined if a mutex is unlocked when not locked.
267     #[inline]
force_unlock(&self)268     pub unsafe fn force_unlock(&self) {
269         self.raw.unlock();
270     }
271 
272     /// Returns the underlying raw mutex object.
273     ///
274     /// Note that you will most likely need to import the `RawMutex` trait from
275     /// `lock_api` to be able to call functions on the raw mutex.
276     ///
277     /// # Safety
278     ///
279     /// This method is unsafe because it allows unlocking a mutex while
280     /// still holding a reference to a `MutexGuard`.
281     #[inline]
raw(&self) -> &R282     pub unsafe fn raw(&self) -> &R {
283         &self.raw
284     }
285 
286     /// Returns a raw pointer to the underlying data.
287     ///
288     /// This is useful when combined with `mem::forget` to hold a lock without
289     /// the need to maintain a `MutexGuard` object alive, for example when
290     /// dealing with FFI.
291     ///
292     /// # Safety
293     ///
294     /// You must ensure that there are no data races when dereferencing the
295     /// returned pointer, for example if the current thread logically owns
296     /// a `MutexGuard` but that guard has been discarded using `mem::forget`.
297     #[inline]
data_ptr(&self) -> *mut T298     pub fn data_ptr(&self) -> *mut T {
299         self.data.get()
300     }
301 
302     /// Creates a new `ArcMutexGuard` without checking if the mutex is locked.
303     ///
304     /// # Safety
305     ///
306     /// This method must only be called if the thread logically holds the lock.
307     ///
308     /// Calling this function when a guard has already been produced is undefined behaviour unless
309     /// the guard was forgotten with `mem::forget`.
310     #[cfg(feature = "arc_lock")]
311     #[inline]
make_arc_guard_unchecked(self: &Arc<Self>) -> ArcMutexGuard<R, T>312     unsafe fn make_arc_guard_unchecked(self: &Arc<Self>) -> ArcMutexGuard<R, T> {
313         ArcMutexGuard {
314             mutex: self.clone(),
315             marker: PhantomData,
316         }
317     }
318 
319     /// Acquires a lock through an `Arc`.
320     ///
321     /// This method is similar to the `lock` method; however, it requires the `Mutex` to be inside of an `Arc`
322     /// and the resulting mutex guard has no lifetime requirements.
323     #[cfg(feature = "arc_lock")]
324     #[inline]
lock_arc(self: &Arc<Self>) -> ArcMutexGuard<R, T>325     pub fn lock_arc(self: &Arc<Self>) -> ArcMutexGuard<R, T> {
326         self.raw.lock();
327         // SAFETY: the locking guarantee is upheld
328         unsafe { self.make_arc_guard_unchecked() }
329     }
330 
331     /// Attempts to acquire a lock through an `Arc`.
332     ///
333     /// This method is similar to the `try_lock` method; however, it requires the `Mutex` to be inside of an
334     /// `Arc` and the resulting mutex guard has no lifetime requirements.
335     #[cfg(feature = "arc_lock")]
336     #[inline]
try_lock_arc(self: &Arc<Self>) -> Option<ArcMutexGuard<R, T>>337     pub fn try_lock_arc(self: &Arc<Self>) -> Option<ArcMutexGuard<R, T>> {
338         if self.raw.try_lock() {
339             // SAFETY: locking guarantee is upheld
340             Some(unsafe { self.make_arc_guard_unchecked() })
341         } else {
342             None
343         }
344     }
345 }
346 
347 impl<R: RawMutexFair, T: ?Sized> Mutex<R, T> {
348     /// Forcibly unlocks the mutex using a fair unlock procotol.
349     ///
350     /// This is useful when combined with `mem::forget` to hold a lock without
351     /// the need to maintain a `MutexGuard` object alive, for example when
352     /// dealing with FFI.
353     ///
354     /// # Safety
355     ///
356     /// This method must only be called if the current thread logically owns a
357     /// `MutexGuard` but that guard has been discarded using `mem::forget`.
358     /// Behavior is undefined if a mutex is unlocked when not locked.
359     #[inline]
force_unlock_fair(&self)360     pub unsafe fn force_unlock_fair(&self) {
361         self.raw.unlock_fair();
362     }
363 }
364 
365 impl<R: RawMutexTimed, T: ?Sized> Mutex<R, T> {
366     /// Attempts to acquire this lock until a timeout is reached.
367     ///
368     /// If the lock could not be acquired before the timeout expired, then
369     /// `None` is returned. Otherwise, an RAII guard is returned. The lock will
370     /// be unlocked when the guard is dropped.
371     #[inline]
try_lock_for(&self, timeout: R::Duration) -> Option<MutexGuard<'_, R, T>>372     pub fn try_lock_for(&self, timeout: R::Duration) -> Option<MutexGuard<'_, R, T>> {
373         if self.raw.try_lock_for(timeout) {
374             // SAFETY: The lock is held, as required.
375             Some(unsafe { self.make_guard_unchecked() })
376         } else {
377             None
378         }
379     }
380 
381     /// Attempts to acquire this lock until a timeout is reached.
382     ///
383     /// If the lock could not be acquired before the timeout expired, then
384     /// `None` is returned. Otherwise, an RAII guard is returned. The lock will
385     /// be unlocked when the guard is dropped.
386     #[inline]
try_lock_until(&self, timeout: R::Instant) -> Option<MutexGuard<'_, R, T>>387     pub fn try_lock_until(&self, timeout: R::Instant) -> Option<MutexGuard<'_, R, T>> {
388         if self.raw.try_lock_until(timeout) {
389             // SAFETY: The lock is held, as required.
390             Some(unsafe { self.make_guard_unchecked() })
391         } else {
392             None
393         }
394     }
395 
396     /// Attempts to acquire this lock through an `Arc` until a timeout is reached.
397     ///
398     /// This method is similar to the `try_lock_for` method; however, it requires the `Mutex` to be inside of an
399     /// `Arc` and the resulting mutex guard has no lifetime requirements.
400     #[cfg(feature = "arc_lock")]
401     #[inline]
try_lock_arc_for(self: &Arc<Self>, timeout: R::Duration) -> Option<ArcMutexGuard<R, T>>402     pub fn try_lock_arc_for(self: &Arc<Self>, timeout: R::Duration) -> Option<ArcMutexGuard<R, T>> {
403         if self.raw.try_lock_for(timeout) {
404             // SAFETY: locking guarantee is upheld
405             Some(unsafe { self.make_arc_guard_unchecked() })
406         } else {
407             None
408         }
409     }
410 
411     /// Attempts to acquire this lock through an `Arc` until a timeout is reached.
412     ///
413     /// This method is similar to the `try_lock_until` method; however, it requires the `Mutex` to be inside of
414     /// an `Arc` and the resulting mutex guard has no lifetime requirements.
415     #[cfg(feature = "arc_lock")]
416     #[inline]
try_lock_arc_until( self: &Arc<Self>, timeout: R::Instant, ) -> Option<ArcMutexGuard<R, T>>417     pub fn try_lock_arc_until(
418         self: &Arc<Self>,
419         timeout: R::Instant,
420     ) -> Option<ArcMutexGuard<R, T>> {
421         if self.raw.try_lock_until(timeout) {
422             // SAFETY: locking guarantee is upheld
423             Some(unsafe { self.make_arc_guard_unchecked() })
424         } else {
425             None
426         }
427     }
428 }
429 
430 impl<R: RawMutex, T: ?Sized + Default> Default for Mutex<R, T> {
431     #[inline]
default() -> Mutex<R, T>432     fn default() -> Mutex<R, T> {
433         Mutex::new(Default::default())
434     }
435 }
436 
437 impl<R: RawMutex, T> From<T> for Mutex<R, T> {
438     #[inline]
from(t: T) -> Mutex<R, T>439     fn from(t: T) -> Mutex<R, T> {
440         Mutex::new(t)
441     }
442 }
443 
444 impl<R: RawMutex, T: ?Sized + fmt::Debug> fmt::Debug for Mutex<R, T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result445     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
446         match self.try_lock() {
447             Some(guard) => f.debug_struct("Mutex").field("data", &&*guard).finish(),
448             None => {
449                 struct LockedPlaceholder;
450                 impl fmt::Debug for LockedPlaceholder {
451                     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
452                         f.write_str("<locked>")
453                     }
454                 }
455 
456                 f.debug_struct("Mutex")
457                     .field("data", &LockedPlaceholder)
458                     .finish()
459             }
460         }
461     }
462 }
463 
464 // Copied and modified from serde
465 #[cfg(feature = "serde")]
466 impl<R, T> Serialize for Mutex<R, T>
467 where
468     R: RawMutex,
469     T: Serialize + ?Sized,
470 {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,471     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
472     where
473         S: Serializer,
474     {
475         self.lock().serialize(serializer)
476     }
477 }
478 
479 #[cfg(feature = "serde")]
480 impl<'de, R, T> Deserialize<'de> for Mutex<R, T>
481 where
482     R: RawMutex,
483     T: Deserialize<'de> + ?Sized,
484 {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,485     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
486     where
487         D: Deserializer<'de>,
488     {
489         Deserialize::deserialize(deserializer).map(Mutex::new)
490     }
491 }
492 
493 /// An RAII implementation of a "scoped lock" of a mutex. When this structure is
494 /// dropped (falls out of scope), the lock will be unlocked.
495 ///
496 /// The data protected by the mutex can be accessed through this guard via its
497 /// `Deref` and `DerefMut` implementations.
498 #[clippy::has_significant_drop]
499 #[must_use = "if unused the Mutex will immediately unlock"]
500 pub struct MutexGuard<'a, R: RawMutex, T: ?Sized> {
501     mutex: &'a Mutex<R, T>,
502     marker: PhantomData<(&'a mut T, R::GuardMarker)>,
503 }
504 
505 unsafe impl<'a, R: RawMutex + Sync + 'a, T: ?Sized + Sync + 'a> Sync for MutexGuard<'a, R, T> {}
506 
507 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> MutexGuard<'a, R, T> {
508     /// Returns a reference to the original `Mutex` object.
mutex(s: &Self) -> &'a Mutex<R, T>509     pub fn mutex(s: &Self) -> &'a Mutex<R, T> {
510         s.mutex
511     }
512 
513     /// Makes a new `MappedMutexGuard` for a component of the locked data.
514     ///
515     /// This operation cannot fail as the `MutexGuard` passed
516     /// in already locked the mutex.
517     ///
518     /// This is an associated function that needs to be
519     /// used as `MutexGuard::map(...)`. A method would interfere with methods of
520     /// the same name on the contents of the locked data.
521     #[inline]
map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U> where F: FnOnce(&mut T) -> &mut U,522     pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U>
523     where
524         F: FnOnce(&mut T) -> &mut U,
525     {
526         let raw = &s.mutex.raw;
527         let data = f(unsafe { &mut *s.mutex.data.get() });
528         mem::forget(s);
529         MappedMutexGuard {
530             raw,
531             data,
532             marker: PhantomData,
533         }
534     }
535 
536     /// Attempts to make a new `MappedMutexGuard` for a component of the
537     /// locked data. The original guard is returned if the closure returns `None`.
538     ///
539     /// This operation cannot fail as the `MutexGuard` passed
540     /// in already locked the mutex.
541     ///
542     /// This is an associated function that needs to be
543     /// used as `MutexGuard::try_map(...)`. A method would interfere with methods of
544     /// the same name on the contents of the locked data.
545     #[inline]
try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self> where F: FnOnce(&mut T) -> Option<&mut U>,546     pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self>
547     where
548         F: FnOnce(&mut T) -> Option<&mut U>,
549     {
550         let raw = &s.mutex.raw;
551         let data = match f(unsafe { &mut *s.mutex.data.get() }) {
552             Some(data) => data,
553             None => return Err(s),
554         };
555         mem::forget(s);
556         Ok(MappedMutexGuard {
557             raw,
558             data,
559             marker: PhantomData,
560         })
561     }
562 
563     /// Temporarily unlocks the mutex to execute the given function.
564     ///
565     /// This is safe because `&mut` guarantees that there exist no other
566     /// references to the data protected by the mutex.
567     #[inline]
unlocked<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,568     pub fn unlocked<F, U>(s: &mut Self, f: F) -> U
569     where
570         F: FnOnce() -> U,
571     {
572         // Safety: A MutexGuard always holds the lock.
573         unsafe {
574             s.mutex.raw.unlock();
575         }
576         defer!(s.mutex.raw.lock());
577         f()
578     }
579 
580     /// Leaks the mutex guard and returns a mutable reference to the data
581     /// protected by the mutex.
582     ///
583     /// This will leave the `Mutex` in a locked state.
584     #[inline]
leak(s: Self) -> &'a mut T585     pub fn leak(s: Self) -> &'a mut T {
586         let r = unsafe { &mut *s.mutex.data.get() };
587         mem::forget(s);
588         r
589     }
590 }
591 
592 impl<'a, R: RawMutexFair + 'a, T: ?Sized + 'a> MutexGuard<'a, R, T> {
593     /// Unlocks the mutex using a fair unlock protocol.
594     ///
595     /// By default, mutexes are unfair and allow the current thread to re-lock
596     /// the mutex before another has the chance to acquire the lock, even if
597     /// that thread has been blocked on the mutex for a long time. This is the
598     /// default because it allows much higher throughput as it avoids forcing a
599     /// context switch on every mutex unlock. This can result in one thread
600     /// acquiring a mutex many more times than other threads.
601     ///
602     /// However in some cases it can be beneficial to ensure fairness by forcing
603     /// the lock to pass on to a waiting thread if there is one. This is done by
604     /// using this method instead of dropping the `MutexGuard` normally.
605     #[inline]
unlock_fair(s: Self)606     pub fn unlock_fair(s: Self) {
607         // Safety: A MutexGuard always holds the lock.
608         unsafe {
609             s.mutex.raw.unlock_fair();
610         }
611         mem::forget(s);
612     }
613 
614     /// Temporarily unlocks the mutex to execute the given function.
615     ///
616     /// The mutex is unlocked using a fair unlock protocol.
617     ///
618     /// This is safe because `&mut` guarantees that there exist no other
619     /// references to the data protected by the mutex.
620     #[inline]
unlocked_fair<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,621     pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U
622     where
623         F: FnOnce() -> U,
624     {
625         // Safety: A MutexGuard always holds the lock.
626         unsafe {
627             s.mutex.raw.unlock_fair();
628         }
629         defer!(s.mutex.raw.lock());
630         f()
631     }
632 
633     /// Temporarily yields the mutex to a waiting thread if there is one.
634     ///
635     /// This method is functionally equivalent to calling `unlock_fair` followed
636     /// by `lock`, however it can be much more efficient in the case where there
637     /// are no waiting threads.
638     #[inline]
bump(s: &mut Self)639     pub fn bump(s: &mut Self) {
640         // Safety: A MutexGuard always holds the lock.
641         unsafe {
642             s.mutex.raw.bump();
643         }
644     }
645 }
646 
647 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Deref for MutexGuard<'a, R, T> {
648     type Target = T;
649     #[inline]
deref(&self) -> &T650     fn deref(&self) -> &T {
651         unsafe { &*self.mutex.data.get() }
652     }
653 }
654 
655 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> DerefMut for MutexGuard<'a, R, T> {
656     #[inline]
deref_mut(&mut self) -> &mut T657     fn deref_mut(&mut self) -> &mut T {
658         unsafe { &mut *self.mutex.data.get() }
659     }
660 }
661 
662 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Drop for MutexGuard<'a, R, T> {
663     #[inline]
drop(&mut self)664     fn drop(&mut self) {
665         // Safety: A MutexGuard always holds the lock.
666         unsafe {
667             self.mutex.raw.unlock();
668         }
669     }
670 }
671 
672 impl<'a, R: RawMutex + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for MutexGuard<'a, R, T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result673     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
674         fmt::Debug::fmt(&**self, f)
675     }
676 }
677 
678 impl<'a, R: RawMutex + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display for MutexGuard<'a, R, T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result679     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
680         (**self).fmt(f)
681     }
682 }
683 
684 #[cfg(feature = "owning_ref")]
685 unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> StableAddress for MutexGuard<'a, R, T> {}
686 
687 /// An RAII mutex guard returned by the `Arc` locking operations on `Mutex`.
688 ///
689 /// This is similar to the `MutexGuard` struct, except instead of using a reference to unlock the `Mutex` it
690 /// uses an `Arc<Mutex>`. This has several advantages, most notably that it has an `'static` lifetime.
691 #[cfg(feature = "arc_lock")]
692 #[clippy::has_significant_drop]
693 #[must_use = "if unused the Mutex will immediately unlock"]
694 pub struct ArcMutexGuard<R: RawMutex, T: ?Sized> {
695     mutex: Arc<Mutex<R, T>>,
696     marker: PhantomData<*const ()>,
697 }
698 
699 #[cfg(feature = "arc_lock")]
700 unsafe impl<R: RawMutex + Send + Sync, T: Send + ?Sized> Send for ArcMutexGuard<R, T> where
701     R::GuardMarker: Send
702 {
703 }
704 #[cfg(feature = "arc_lock")]
705 unsafe impl<R: RawMutex + Sync, T: Sync + ?Sized> Sync for ArcMutexGuard<R, T> where
706     R::GuardMarker: Sync
707 {
708 }
709 
710 #[cfg(feature = "arc_lock")]
711 impl<R: RawMutex, T: ?Sized> ArcMutexGuard<R, T> {
712     /// Returns a reference to the `Mutex` this is guarding, contained in its `Arc`.
713     #[inline]
mutex(s: &Self) -> &Arc<Mutex<R, T>>714     pub fn mutex(s: &Self) -> &Arc<Mutex<R, T>> {
715         &s.mutex
716     }
717 
718     /// Unlocks the mutex and returns the `Arc` that was held by the [`ArcMutexGuard`].
719     #[inline]
into_arc(s: Self) -> Arc<Mutex<R, T>>720     pub fn into_arc(s: Self) -> Arc<Mutex<R, T>> {
721         // Safety: Skip our Drop impl and manually unlock the mutex.
722         let arc = unsafe { ptr::read(&s.mutex) };
723         mem::forget(s);
724         unsafe {
725             arc.raw.unlock();
726         }
727         arc
728     }
729 
730     /// Temporarily unlocks the mutex to execute the given function.
731     ///
732     /// This is safe because `&mut` guarantees that there exist no other
733     /// references to the data protected by the mutex.
734     #[inline]
unlocked<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,735     pub fn unlocked<F, U>(s: &mut Self, f: F) -> U
736     where
737         F: FnOnce() -> U,
738     {
739         // Safety: A MutexGuard always holds the lock.
740         unsafe {
741             s.mutex.raw.unlock();
742         }
743         defer!(s.mutex.raw.lock());
744         f()
745     }
746 }
747 
748 #[cfg(feature = "arc_lock")]
749 impl<R: RawMutexFair, T: ?Sized> ArcMutexGuard<R, T> {
750     /// Unlocks the mutex using a fair unlock protocol.
751     ///
752     /// This is functionally identical to the `unlock_fair` method on [`MutexGuard`].
753     #[inline]
unlock_fair(s: Self)754     pub fn unlock_fair(s: Self) {
755         // Safety: A MutexGuard always holds the lock.
756         unsafe {
757             s.mutex.raw.unlock_fair();
758         }
759 
760         // SAFETY: make sure the Arc gets it reference decremented
761         let mut s = ManuallyDrop::new(s);
762         unsafe { ptr::drop_in_place(&mut s.mutex) };
763     }
764 
765     /// Temporarily unlocks the mutex to execute the given function.
766     ///
767     /// This is functionally identical to the `unlocked_fair` method on [`MutexGuard`].
768     #[inline]
unlocked_fair<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,769     pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U
770     where
771         F: FnOnce() -> U,
772     {
773         // Safety: A MutexGuard always holds the lock.
774         unsafe {
775             s.mutex.raw.unlock_fair();
776         }
777         defer!(s.mutex.raw.lock());
778         f()
779     }
780 
781     /// Temporarily yields the mutex to a waiting thread if there is one.
782     ///
783     /// This is functionally identical to the `bump` method on [`MutexGuard`].
784     #[inline]
bump(s: &mut Self)785     pub fn bump(s: &mut Self) {
786         // Safety: A MutexGuard always holds the lock.
787         unsafe {
788             s.mutex.raw.bump();
789         }
790     }
791 }
792 
793 #[cfg(feature = "arc_lock")]
794 impl<R: RawMutex, T: ?Sized> Deref for ArcMutexGuard<R, T> {
795     type Target = T;
796     #[inline]
deref(&self) -> &T797     fn deref(&self) -> &T {
798         unsafe { &*self.mutex.data.get() }
799     }
800 }
801 
802 #[cfg(feature = "arc_lock")]
803 impl<R: RawMutex, T: ?Sized> DerefMut for ArcMutexGuard<R, T> {
804     #[inline]
deref_mut(&mut self) -> &mut T805     fn deref_mut(&mut self) -> &mut T {
806         unsafe { &mut *self.mutex.data.get() }
807     }
808 }
809 
810 #[cfg(feature = "arc_lock")]
811 impl<R: RawMutex, T: ?Sized> Drop for ArcMutexGuard<R, T> {
812     #[inline]
drop(&mut self)813     fn drop(&mut self) {
814         // Safety: A MutexGuard always holds the lock.
815         unsafe {
816             self.mutex.raw.unlock();
817         }
818     }
819 }
820 
821 /// An RAII mutex guard returned by `MutexGuard::map`, which can point to a
822 /// subfield of the protected data.
823 ///
824 /// The main difference between `MappedMutexGuard` and `MutexGuard` is that the
825 /// former doesn't support temporarily unlocking and re-locking, since that
826 /// could introduce soundness issues if the locked object is modified by another
827 /// thread.
828 #[clippy::has_significant_drop]
829 #[must_use = "if unused the Mutex will immediately unlock"]
830 pub struct MappedMutexGuard<'a, R: RawMutex, T: ?Sized> {
831     raw: &'a R,
832     data: *mut T,
833     marker: PhantomData<&'a mut T>,
834 }
835 
836 unsafe impl<'a, R: RawMutex + Sync + 'a, T: ?Sized + Sync + 'a> Sync
837     for MappedMutexGuard<'a, R, T>
838 {
839 }
840 unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + Send + 'a> Send for MappedMutexGuard<'a, R, T> where
841     R::GuardMarker: Send
842 {
843 }
844 
845 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> MappedMutexGuard<'a, R, T> {
846     /// Makes a new `MappedMutexGuard` for a component of the locked data.
847     ///
848     /// This operation cannot fail as the `MappedMutexGuard` passed
849     /// in already locked the mutex.
850     ///
851     /// This is an associated function that needs to be
852     /// used as `MappedMutexGuard::map(...)`. A method would interfere with methods of
853     /// the same name on the contents of the locked data.
854     #[inline]
map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U> where F: FnOnce(&mut T) -> &mut U,855     pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U>
856     where
857         F: FnOnce(&mut T) -> &mut U,
858     {
859         let raw = s.raw;
860         let data = f(unsafe { &mut *s.data });
861         mem::forget(s);
862         MappedMutexGuard {
863             raw,
864             data,
865             marker: PhantomData,
866         }
867     }
868 
869     /// Attempts to make a new `MappedMutexGuard` for a component of the
870     /// locked data. The original guard is returned if the closure returns `None`.
871     ///
872     /// This operation cannot fail as the `MappedMutexGuard` passed
873     /// in already locked the mutex.
874     ///
875     /// This is an associated function that needs to be
876     /// used as `MappedMutexGuard::try_map(...)`. A method would interfere with methods of
877     /// the same name on the contents of the locked data.
878     #[inline]
try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self> where F: FnOnce(&mut T) -> Option<&mut U>,879     pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self>
880     where
881         F: FnOnce(&mut T) -> Option<&mut U>,
882     {
883         let raw = s.raw;
884         let data = match f(unsafe { &mut *s.data }) {
885             Some(data) => data,
886             None => return Err(s),
887         };
888         mem::forget(s);
889         Ok(MappedMutexGuard {
890             raw,
891             data,
892             marker: PhantomData,
893         })
894     }
895 }
896 
897 impl<'a, R: RawMutexFair + 'a, T: ?Sized + 'a> MappedMutexGuard<'a, R, T> {
898     /// Unlocks the mutex using a fair unlock protocol.
899     ///
900     /// By default, mutexes are unfair and allow the current thread to re-lock
901     /// the mutex before another has the chance to acquire the lock, even if
902     /// that thread has been blocked on the mutex for a long time. This is the
903     /// default because it allows much higher throughput as it avoids forcing a
904     /// context switch on every mutex unlock. This can result in one thread
905     /// acquiring a mutex many more times than other threads.
906     ///
907     /// However in some cases it can be beneficial to ensure fairness by forcing
908     /// the lock to pass on to a waiting thread if there is one. This is done by
909     /// using this method instead of dropping the `MutexGuard` normally.
910     #[inline]
unlock_fair(s: Self)911     pub fn unlock_fair(s: Self) {
912         // Safety: A MutexGuard always holds the lock.
913         unsafe {
914             s.raw.unlock_fair();
915         }
916         mem::forget(s);
917     }
918 }
919 
920 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Deref for MappedMutexGuard<'a, R, T> {
921     type Target = T;
922     #[inline]
deref(&self) -> &T923     fn deref(&self) -> &T {
924         unsafe { &*self.data }
925     }
926 }
927 
928 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> DerefMut for MappedMutexGuard<'a, R, T> {
929     #[inline]
deref_mut(&mut self) -> &mut T930     fn deref_mut(&mut self) -> &mut T {
931         unsafe { &mut *self.data }
932     }
933 }
934 
935 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Drop for MappedMutexGuard<'a, R, T> {
936     #[inline]
drop(&mut self)937     fn drop(&mut self) {
938         // Safety: A MappedMutexGuard always holds the lock.
939         unsafe {
940             self.raw.unlock();
941         }
942     }
943 }
944 
945 impl<'a, R: RawMutex + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for MappedMutexGuard<'a, R, T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result946     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
947         fmt::Debug::fmt(&**self, f)
948     }
949 }
950 
951 impl<'a, R: RawMutex + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display
952     for MappedMutexGuard<'a, R, T>
953 {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result954     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
955         (**self).fmt(f)
956     }
957 }
958 
959 #[cfg(feature = "owning_ref")]
960 unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> StableAddress for MappedMutexGuard<'a, R, T> {}
961