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