• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(feature = "nightly")]
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(feature = "nightly"))]
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     /// # Safety
193     ///
194     /// The lock must be held when calling this method.
195     #[inline]
guard(&self) -> MutexGuard<'_, R, T>196     unsafe fn guard(&self) -> MutexGuard<'_, R, T> {
197         MutexGuard {
198             mutex: self,
199             marker: PhantomData,
200         }
201     }
202 
203     /// Acquires a mutex, blocking the current thread until it is able to do so.
204     ///
205     /// This function will block the local thread until it is available to acquire
206     /// the mutex. Upon returning, the thread is the only thread with the mutex
207     /// held. An RAII guard is returned to allow scoped unlock of the lock. When
208     /// the guard goes out of scope, the mutex will be unlocked.
209     ///
210     /// Attempts to lock a mutex in the thread which already holds the lock will
211     /// result in a deadlock.
212     #[inline]
lock(&self) -> MutexGuard<'_, R, T>213     pub fn lock(&self) -> MutexGuard<'_, R, T> {
214         self.raw.lock();
215         // SAFETY: The lock is held, as required.
216         unsafe { self.guard() }
217     }
218 
219     /// Attempts to acquire this lock.
220     ///
221     /// If the lock could not be acquired at this time, then `None` is returned.
222     /// Otherwise, an RAII guard is returned. The lock will be unlocked when the
223     /// guard is dropped.
224     ///
225     /// This function does not block.
226     #[inline]
try_lock(&self) -> Option<MutexGuard<'_, R, T>>227     pub fn try_lock(&self) -> Option<MutexGuard<'_, R, T>> {
228         if self.raw.try_lock() {
229             // SAFETY: The lock is held, as required.
230             Some(unsafe { self.guard() })
231         } else {
232             None
233         }
234     }
235 
236     /// Returns a mutable reference to the underlying data.
237     ///
238     /// Since this call borrows the `Mutex` mutably, no actual locking needs to
239     /// take place---the mutable borrow statically guarantees no locks exist.
240     #[inline]
get_mut(&mut self) -> &mut T241     pub fn get_mut(&mut self) -> &mut T {
242         unsafe { &mut *self.data.get() }
243     }
244 
245     /// Checks whether the mutex is currently locked.
246     #[inline]
is_locked(&self) -> bool247     pub fn is_locked(&self) -> bool {
248         self.raw.is_locked()
249     }
250 
251     /// Forcibly unlocks the mutex.
252     ///
253     /// This is useful when combined with `mem::forget` to hold a lock without
254     /// the need to maintain a `MutexGuard` object alive, for example when
255     /// dealing with FFI.
256     ///
257     /// # Safety
258     ///
259     /// This method must only be called if the current thread logically owns a
260     /// `MutexGuard` but that guard has be discarded using `mem::forget`.
261     /// Behavior is undefined if a mutex is unlocked when not locked.
262     #[inline]
force_unlock(&self)263     pub unsafe fn force_unlock(&self) {
264         self.raw.unlock();
265     }
266 
267     /// Returns the underlying raw mutex object.
268     ///
269     /// Note that you will most likely need to import the `RawMutex` trait from
270     /// `lock_api` to be able to call functions on the raw mutex.
271     ///
272     /// # Safety
273     ///
274     /// This method is unsafe because it allows unlocking a mutex while
275     /// still holding a reference to a `MutexGuard`.
276     #[inline]
raw(&self) -> &R277     pub unsafe fn raw(&self) -> &R {
278         &self.raw
279     }
280 
281     /// Returns a raw pointer to the underlying data.
282     ///
283     /// This is useful when combined with `mem::forget` to hold a lock without
284     /// the need to maintain a `MutexGuard` object alive, for example when
285     /// dealing with FFI.
286     ///
287     /// # Safety
288     ///
289     /// You must ensure that there are no data races when dereferencing the
290     /// returned pointer, for example if the current thread logically owns
291     /// a `MutexGuard` but that guard has been discarded using `mem::forget`.
292     #[inline]
data_ptr(&self) -> *mut T293     pub fn data_ptr(&self) -> *mut T {
294         self.data.get()
295     }
296 
297     /// # Safety
298     ///
299     /// The lock needs to be held for the behavior of this function to be defined.
300     #[cfg(feature = "arc_lock")]
301     #[inline]
guard_arc(self: &Arc<Self>) -> ArcMutexGuard<R, T>302     unsafe fn guard_arc(self: &Arc<Self>) -> ArcMutexGuard<R, T> {
303         ArcMutexGuard {
304             mutex: self.clone(),
305             marker: PhantomData,
306         }
307     }
308 
309     /// Acquires a lock through an `Arc`.
310     ///
311     /// This method is similar to the `lock` method; however, it requires the `Mutex` to be inside of an `Arc`
312     /// and the resulting mutex guard has no lifetime requirements.
313     #[cfg(feature = "arc_lock")]
314     #[inline]
lock_arc(self: &Arc<Self>) -> ArcMutexGuard<R, T>315     pub fn lock_arc(self: &Arc<Self>) -> ArcMutexGuard<R, T> {
316         self.raw.lock();
317         // SAFETY: the locking guarantee is upheld
318         unsafe { self.guard_arc() }
319     }
320 
321     /// Attempts to acquire a lock through an `Arc`.
322     ///
323     /// This method is similar to the `try_lock` method; however, it requires the `Mutex` to be inside of an
324     /// `Arc` and the resulting mutex guard has no lifetime requirements.
325     #[cfg(feature = "arc_lock")]
326     #[inline]
try_lock_arc(self: &Arc<Self>) -> Option<ArcMutexGuard<R, T>>327     pub fn try_lock_arc(self: &Arc<Self>) -> Option<ArcMutexGuard<R, T>> {
328         if self.raw.try_lock() {
329             // SAFETY: locking guarantee is upheld
330             Some(unsafe { self.guard_arc() })
331         } else {
332             None
333         }
334     }
335 }
336 
337 impl<R: RawMutexFair, T: ?Sized> Mutex<R, T> {
338     /// Forcibly unlocks the mutex using a fair unlock procotol.
339     ///
340     /// This is useful when combined with `mem::forget` to hold a lock without
341     /// the need to maintain a `MutexGuard` object alive, for example when
342     /// dealing with FFI.
343     ///
344     /// # Safety
345     ///
346     /// This method must only be called if the current thread logically owns a
347     /// `MutexGuard` but that guard has be discarded using `mem::forget`.
348     /// Behavior is undefined if a mutex is unlocked when not locked.
349     #[inline]
force_unlock_fair(&self)350     pub unsafe fn force_unlock_fair(&self) {
351         self.raw.unlock_fair();
352     }
353 }
354 
355 impl<R: RawMutexTimed, T: ?Sized> Mutex<R, T> {
356     /// Attempts to acquire this lock until a timeout is reached.
357     ///
358     /// If the lock could not be acquired before the timeout expired, then
359     /// `None` is returned. Otherwise, an RAII guard is returned. The lock will
360     /// be unlocked when the guard is dropped.
361     #[inline]
try_lock_for(&self, timeout: R::Duration) -> Option<MutexGuard<'_, R, T>>362     pub fn try_lock_for(&self, timeout: R::Duration) -> Option<MutexGuard<'_, R, T>> {
363         if self.raw.try_lock_for(timeout) {
364             // SAFETY: The lock is held, as required.
365             Some(unsafe { self.guard() })
366         } else {
367             None
368         }
369     }
370 
371     /// Attempts to acquire this lock until a timeout is reached.
372     ///
373     /// If the lock could not be acquired before the timeout expired, then
374     /// `None` is returned. Otherwise, an RAII guard is returned. The lock will
375     /// be unlocked when the guard is dropped.
376     #[inline]
try_lock_until(&self, timeout: R::Instant) -> Option<MutexGuard<'_, R, T>>377     pub fn try_lock_until(&self, timeout: R::Instant) -> Option<MutexGuard<'_, R, T>> {
378         if self.raw.try_lock_until(timeout) {
379             // SAFETY: The lock is held, as required.
380             Some(unsafe { self.guard() })
381         } else {
382             None
383         }
384     }
385 
386     /// Attempts to acquire this lock through an `Arc` until a timeout is reached.
387     ///
388     /// This method is similar to the `try_lock_for` method; however, it requires the `Mutex` to be inside of an
389     /// `Arc` and the resulting mutex guard has no lifetime requirements.
390     #[cfg(feature = "arc_lock")]
391     #[inline]
try_lock_arc_for(self: &Arc<Self>, timeout: R::Duration) -> Option<ArcMutexGuard<R, T>>392     pub fn try_lock_arc_for(self: &Arc<Self>, timeout: R::Duration) -> Option<ArcMutexGuard<R, T>> {
393         if self.raw.try_lock_for(timeout) {
394             // SAFETY: locking guarantee is upheld
395             Some(unsafe { self.guard_arc() })
396         } else {
397             None
398         }
399     }
400 
401     /// Attempts to acquire this lock through an `Arc` until a timeout is reached.
402     ///
403     /// This method is similar to the `try_lock_until` method; however, it requires the `Mutex` to be inside of
404     /// an `Arc` and the resulting mutex guard has no lifetime requirements.
405     #[cfg(feature = "arc_lock")]
406     #[inline]
try_lock_arc_until( self: &Arc<Self>, timeout: R::Instant, ) -> Option<ArcMutexGuard<R, T>>407     pub fn try_lock_arc_until(
408         self: &Arc<Self>,
409         timeout: R::Instant,
410     ) -> Option<ArcMutexGuard<R, T>> {
411         if self.raw.try_lock_until(timeout) {
412             // SAFETY: locking guarantee is upheld
413             Some(unsafe { self.guard_arc() })
414         } else {
415             None
416         }
417     }
418 }
419 
420 impl<R: RawMutex, T: ?Sized + Default> Default for Mutex<R, T> {
421     #[inline]
default() -> Mutex<R, T>422     fn default() -> Mutex<R, T> {
423         Mutex::new(Default::default())
424     }
425 }
426 
427 impl<R: RawMutex, T> From<T> for Mutex<R, T> {
428     #[inline]
from(t: T) -> Mutex<R, T>429     fn from(t: T) -> Mutex<R, T> {
430         Mutex::new(t)
431     }
432 }
433 
434 impl<R: RawMutex, T: ?Sized + fmt::Debug> fmt::Debug for Mutex<R, T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result435     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
436         match self.try_lock() {
437             Some(guard) => f.debug_struct("Mutex").field("data", &&*guard).finish(),
438             None => {
439                 struct LockedPlaceholder;
440                 impl fmt::Debug for LockedPlaceholder {
441                     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
442                         f.write_str("<locked>")
443                     }
444                 }
445 
446                 f.debug_struct("Mutex")
447                     .field("data", &LockedPlaceholder)
448                     .finish()
449             }
450         }
451     }
452 }
453 
454 // Copied and modified from serde
455 #[cfg(feature = "serde")]
456 impl<R, T> Serialize for Mutex<R, T>
457 where
458     R: RawMutex,
459     T: Serialize + ?Sized,
460 {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,461     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
462     where
463         S: Serializer,
464     {
465         self.lock().serialize(serializer)
466     }
467 }
468 
469 #[cfg(feature = "serde")]
470 impl<'de, R, T> Deserialize<'de> for Mutex<R, T>
471 where
472     R: RawMutex,
473     T: Deserialize<'de> + ?Sized,
474 {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,475     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
476     where
477         D: Deserializer<'de>,
478     {
479         Deserialize::deserialize(deserializer).map(Mutex::new)
480     }
481 }
482 
483 /// An RAII implementation of a "scoped lock" of a mutex. When this structure is
484 /// dropped (falls out of scope), the lock will be unlocked.
485 ///
486 /// The data protected by the mutex can be accessed through this guard via its
487 /// `Deref` and `DerefMut` implementations.
488 #[must_use = "if unused the Mutex will immediately unlock"]
489 pub struct MutexGuard<'a, R: RawMutex, T: ?Sized> {
490     mutex: &'a Mutex<R, T>,
491     marker: PhantomData<(&'a mut T, R::GuardMarker)>,
492 }
493 
494 unsafe impl<'a, R: RawMutex + Sync + 'a, T: ?Sized + Sync + 'a> Sync for MutexGuard<'a, R, T> {}
495 
496 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> MutexGuard<'a, R, T> {
497     /// Returns a reference to the original `Mutex` object.
mutex(s: &Self) -> &'a Mutex<R, T>498     pub fn mutex(s: &Self) -> &'a Mutex<R, T> {
499         s.mutex
500     }
501 
502     /// Makes a new `MappedMutexGuard` for a component of the locked data.
503     ///
504     /// This operation cannot fail as the `MutexGuard` passed
505     /// in already locked the mutex.
506     ///
507     /// This is an associated function that needs to be
508     /// used as `MutexGuard::map(...)`. A method would interfere with methods of
509     /// the same name on the contents of the locked data.
510     #[inline]
map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U> where F: FnOnce(&mut T) -> &mut U,511     pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U>
512     where
513         F: FnOnce(&mut T) -> &mut U,
514     {
515         let raw = &s.mutex.raw;
516         let data = f(unsafe { &mut *s.mutex.data.get() });
517         mem::forget(s);
518         MappedMutexGuard {
519             raw,
520             data,
521             marker: PhantomData,
522         }
523     }
524 
525     /// Attempts to make a new `MappedMutexGuard` for a component of the
526     /// locked data. The original guard is returned if the closure returns `None`.
527     ///
528     /// This operation cannot fail as the `MutexGuard` passed
529     /// in already locked the mutex.
530     ///
531     /// This is an associated function that needs to be
532     /// used as `MutexGuard::try_map(...)`. A method would interfere with methods of
533     /// the same name on the contents of the locked data.
534     #[inline]
try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self> where F: FnOnce(&mut T) -> Option<&mut U>,535     pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self>
536     where
537         F: FnOnce(&mut T) -> Option<&mut U>,
538     {
539         let raw = &s.mutex.raw;
540         let data = match f(unsafe { &mut *s.mutex.data.get() }) {
541             Some(data) => data,
542             None => return Err(s),
543         };
544         mem::forget(s);
545         Ok(MappedMutexGuard {
546             raw,
547             data,
548             marker: PhantomData,
549         })
550     }
551 
552     /// Temporarily unlocks the mutex to execute the given function.
553     ///
554     /// This is safe because `&mut` guarantees that there exist no other
555     /// references to the data protected by the mutex.
556     #[inline]
unlocked<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,557     pub fn unlocked<F, U>(s: &mut Self, f: F) -> U
558     where
559         F: FnOnce() -> U,
560     {
561         // Safety: A MutexGuard always holds the lock.
562         unsafe {
563             s.mutex.raw.unlock();
564         }
565         defer!(s.mutex.raw.lock());
566         f()
567     }
568 }
569 
570 impl<'a, R: RawMutexFair + 'a, T: ?Sized + 'a> MutexGuard<'a, R, T> {
571     /// Unlocks the mutex using a fair unlock protocol.
572     ///
573     /// By default, mutexes are unfair and allow the current thread to re-lock
574     /// the mutex before another has the chance to acquire the lock, even if
575     /// that thread has been blocked on the mutex for a long time. This is the
576     /// default because it allows much higher throughput as it avoids forcing a
577     /// context switch on every mutex unlock. This can result in one thread
578     /// acquiring a mutex many more times than other threads.
579     ///
580     /// However in some cases it can be beneficial to ensure fairness by forcing
581     /// the lock to pass on to a waiting thread if there is one. This is done by
582     /// using this method instead of dropping the `MutexGuard` normally.
583     #[inline]
unlock_fair(s: Self)584     pub fn unlock_fair(s: Self) {
585         // Safety: A MutexGuard always holds the lock.
586         unsafe {
587             s.mutex.raw.unlock_fair();
588         }
589         mem::forget(s);
590     }
591 
592     /// Temporarily unlocks the mutex to execute the given function.
593     ///
594     /// The mutex is unlocked using a fair unlock protocol.
595     ///
596     /// This is safe because `&mut` guarantees that there exist no other
597     /// references to the data protected by the mutex.
598     #[inline]
unlocked_fair<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,599     pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U
600     where
601         F: FnOnce() -> U,
602     {
603         // Safety: A MutexGuard always holds the lock.
604         unsafe {
605             s.mutex.raw.unlock_fair();
606         }
607         defer!(s.mutex.raw.lock());
608         f()
609     }
610 
611     /// Temporarily yields the mutex to a waiting thread if there is one.
612     ///
613     /// This method is functionally equivalent to calling `unlock_fair` followed
614     /// by `lock`, however it can be much more efficient in the case where there
615     /// are no waiting threads.
616     #[inline]
bump(s: &mut Self)617     pub fn bump(s: &mut Self) {
618         // Safety: A MutexGuard always holds the lock.
619         unsafe {
620             s.mutex.raw.bump();
621         }
622     }
623 }
624 
625 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Deref for MutexGuard<'a, R, T> {
626     type Target = T;
627     #[inline]
deref(&self) -> &T628     fn deref(&self) -> &T {
629         unsafe { &*self.mutex.data.get() }
630     }
631 }
632 
633 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> DerefMut for MutexGuard<'a, R, T> {
634     #[inline]
deref_mut(&mut self) -> &mut T635     fn deref_mut(&mut self) -> &mut T {
636         unsafe { &mut *self.mutex.data.get() }
637     }
638 }
639 
640 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Drop for MutexGuard<'a, R, T> {
641     #[inline]
drop(&mut self)642     fn drop(&mut self) {
643         // Safety: A MutexGuard always holds the lock.
644         unsafe {
645             self.mutex.raw.unlock();
646         }
647     }
648 }
649 
650 impl<'a, R: RawMutex + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for MutexGuard<'a, R, T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result651     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
652         fmt::Debug::fmt(&**self, f)
653     }
654 }
655 
656 impl<'a, R: RawMutex + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display for MutexGuard<'a, R, T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result657     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
658         (**self).fmt(f)
659     }
660 }
661 
662 #[cfg(feature = "owning_ref")]
663 unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> StableAddress for MutexGuard<'a, R, T> {}
664 
665 /// An RAII mutex guard returned by the `Arc` locking operations on `Mutex`.
666 ///
667 /// This is similar to the `MutexGuard` struct, except instead of using a reference to unlock the `Mutex` it
668 /// uses an `Arc<Mutex>`. This has several advantages, most notably that it has an `'static` lifetime.
669 #[cfg(feature = "arc_lock")]
670 #[must_use = "if unused the Mutex will immediately unlock"]
671 pub struct ArcMutexGuard<R: RawMutex, T: ?Sized> {
672     mutex: Arc<Mutex<R, T>>,
673     marker: PhantomData<R::GuardMarker>,
674 }
675 
676 #[cfg(feature = "arc_lock")]
677 impl<R: RawMutex, T: ?Sized> ArcMutexGuard<R, T> {
678     /// Returns a reference to the `Mutex` this is guarding, contained in its `Arc`.
679     #[inline]
mutex(&self) -> &Arc<Mutex<R, T>>680     pub fn mutex(&self) -> &Arc<Mutex<R, T>> {
681         &self.mutex
682     }
683 
684     /// Temporarily unlocks the mutex to execute the given function.
685     ///
686     /// This is safe because `&mut` guarantees that there exist no other
687     /// references to the data protected by the mutex.
688     #[inline]
unlocked<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,689     pub fn unlocked<F, U>(s: &mut Self, f: F) -> U
690     where
691         F: FnOnce() -> U,
692     {
693         // Safety: A MutexGuard always holds the lock.
694         unsafe {
695             s.mutex.raw.unlock();
696         }
697         defer!(s.mutex.raw.lock());
698         f()
699     }
700 }
701 
702 #[cfg(feature = "arc_lock")]
703 impl<R: RawMutexFair, T: ?Sized> ArcMutexGuard<R, T> {
704     /// Unlocks the mutex using a fair unlock protocol.
705     ///
706     /// This is functionally identical to the `unlock_fair` method on [`MutexGuard`].
707     #[inline]
unlock_fair(s: Self)708     pub fn unlock_fair(s: Self) {
709         // Safety: A MutexGuard always holds the lock.
710         unsafe {
711             s.mutex.raw.unlock_fair();
712         }
713 
714         // SAFETY: make sure the Arc gets it reference decremented
715         let mut s = ManuallyDrop::new(s);
716         unsafe { ptr::drop_in_place(&mut s.mutex) };
717     }
718 
719     /// Temporarily unlocks the mutex to execute the given function.
720     ///
721     /// This is functionally identical to the `unlocked_fair` method on [`MutexGuard`].
722     #[inline]
unlocked_fair<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,723     pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U
724     where
725         F: FnOnce() -> U,
726     {
727         // Safety: A MutexGuard always holds the lock.
728         unsafe {
729             s.mutex.raw.unlock_fair();
730         }
731         defer!(s.mutex.raw.lock());
732         f()
733     }
734 
735     /// Temporarily yields the mutex to a waiting thread if there is one.
736     ///
737     /// This is functionally identical to the `bump` method on [`MutexGuard`].
738     #[inline]
bump(s: &mut Self)739     pub fn bump(s: &mut Self) {
740         // Safety: A MutexGuard always holds the lock.
741         unsafe {
742             s.mutex.raw.bump();
743         }
744     }
745 }
746 
747 #[cfg(feature = "arc_lock")]
748 impl<R: RawMutex, T: ?Sized> Deref for ArcMutexGuard<R, T> {
749     type Target = T;
750     #[inline]
deref(&self) -> &T751     fn deref(&self) -> &T {
752         unsafe { &*self.mutex.data.get() }
753     }
754 }
755 
756 #[cfg(feature = "arc_lock")]
757 impl<R: RawMutex, T: ?Sized> DerefMut for ArcMutexGuard<R, T> {
758     #[inline]
deref_mut(&mut self) -> &mut T759     fn deref_mut(&mut self) -> &mut T {
760         unsafe { &mut *self.mutex.data.get() }
761     }
762 }
763 
764 #[cfg(feature = "arc_lock")]
765 impl<R: RawMutex, T: ?Sized> Drop for ArcMutexGuard<R, T> {
766     #[inline]
drop(&mut self)767     fn drop(&mut self) {
768         // Safety: A MutexGuard always holds the lock.
769         unsafe {
770             self.mutex.raw.unlock();
771         }
772     }
773 }
774 
775 /// An RAII mutex guard returned by `MutexGuard::map`, which can point to a
776 /// subfield of the protected data.
777 ///
778 /// The main difference between `MappedMutexGuard` and `MutexGuard` is that the
779 /// former doesn't support temporarily unlocking and re-locking, since that
780 /// could introduce soundness issues if the locked object is modified by another
781 /// thread.
782 #[must_use = "if unused the Mutex will immediately unlock"]
783 pub struct MappedMutexGuard<'a, R: RawMutex, T: ?Sized> {
784     raw: &'a R,
785     data: *mut T,
786     marker: PhantomData<&'a mut T>,
787 }
788 
789 unsafe impl<'a, R: RawMutex + Sync + 'a, T: ?Sized + Sync + 'a> Sync
790     for MappedMutexGuard<'a, R, T>
791 {
792 }
793 unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + Send + 'a> Send for MappedMutexGuard<'a, R, T> where
794     R::GuardMarker: Send
795 {
796 }
797 
798 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> MappedMutexGuard<'a, R, T> {
799     /// Makes a new `MappedMutexGuard` for a component of the locked data.
800     ///
801     /// This operation cannot fail as the `MappedMutexGuard` passed
802     /// in already locked the mutex.
803     ///
804     /// This is an associated function that needs to be
805     /// used as `MappedMutexGuard::map(...)`. A method would interfere with methods of
806     /// the same name on the contents of the locked data.
807     #[inline]
map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U> where F: FnOnce(&mut T) -> &mut U,808     pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U>
809     where
810         F: FnOnce(&mut T) -> &mut U,
811     {
812         let raw = s.raw;
813         let data = f(unsafe { &mut *s.data });
814         mem::forget(s);
815         MappedMutexGuard {
816             raw,
817             data,
818             marker: PhantomData,
819         }
820     }
821 
822     /// Attempts to make a new `MappedMutexGuard` for a component of the
823     /// locked data. The original guard is returned if the closure returns `None`.
824     ///
825     /// This operation cannot fail as the `MappedMutexGuard` passed
826     /// in already locked the mutex.
827     ///
828     /// This is an associated function that needs to be
829     /// used as `MappedMutexGuard::try_map(...)`. A method would interfere with methods of
830     /// the same name on the contents of the locked data.
831     #[inline]
try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self> where F: FnOnce(&mut T) -> Option<&mut U>,832     pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self>
833     where
834         F: FnOnce(&mut T) -> Option<&mut U>,
835     {
836         let raw = s.raw;
837         let data = match f(unsafe { &mut *s.data }) {
838             Some(data) => data,
839             None => return Err(s),
840         };
841         mem::forget(s);
842         Ok(MappedMutexGuard {
843             raw,
844             data,
845             marker: PhantomData,
846         })
847     }
848 }
849 
850 impl<'a, R: RawMutexFair + 'a, T: ?Sized + 'a> MappedMutexGuard<'a, R, T> {
851     /// Unlocks the mutex using a fair unlock protocol.
852     ///
853     /// By default, mutexes are unfair and allow the current thread to re-lock
854     /// the mutex before another has the chance to acquire the lock, even if
855     /// that thread has been blocked on the mutex for a long time. This is the
856     /// default because it allows much higher throughput as it avoids forcing a
857     /// context switch on every mutex unlock. This can result in one thread
858     /// acquiring a mutex many more times than other threads.
859     ///
860     /// However in some cases it can be beneficial to ensure fairness by forcing
861     /// the lock to pass on to a waiting thread if there is one. This is done by
862     /// using this method instead of dropping the `MutexGuard` normally.
863     #[inline]
unlock_fair(s: Self)864     pub fn unlock_fair(s: Self) {
865         // Safety: A MutexGuard always holds the lock.
866         unsafe {
867             s.raw.unlock_fair();
868         }
869         mem::forget(s);
870     }
871 }
872 
873 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Deref for MappedMutexGuard<'a, R, T> {
874     type Target = T;
875     #[inline]
deref(&self) -> &T876     fn deref(&self) -> &T {
877         unsafe { &*self.data }
878     }
879 }
880 
881 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> DerefMut for MappedMutexGuard<'a, R, T> {
882     #[inline]
deref_mut(&mut self) -> &mut T883     fn deref_mut(&mut self) -> &mut T {
884         unsafe { &mut *self.data }
885     }
886 }
887 
888 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Drop for MappedMutexGuard<'a, R, T> {
889     #[inline]
drop(&mut self)890     fn drop(&mut self) {
891         // Safety: A MappedMutexGuard always holds the lock.
892         unsafe {
893             self.raw.unlock();
894         }
895     }
896 }
897 
898 impl<'a, R: RawMutex + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for MappedMutexGuard<'a, R, T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result899     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
900         fmt::Debug::fmt(&**self, f)
901     }
902 }
903 
904 impl<'a, R: RawMutex + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display
905     for MappedMutexGuard<'a, R, T>
906 {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result907     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
908         (**self).fmt(f)
909     }
910 }
911 
912 #[cfg(feature = "owning_ref")]
913 unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> StableAddress for MappedMutexGuard<'a, R, T> {}
914