lock_api/
mutex.rs

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
8use core::cell::UnsafeCell;
9use core::fmt;
10use core::marker::PhantomData;
11use core::mem;
12use core::ops::{Deref, DerefMut};
13
14#[cfg(feature = "arc_lock")]
15use alloc::sync::Arc;
16#[cfg(feature = "arc_lock")]
17use core::mem::ManuallyDrop;
18#[cfg(feature = "arc_lock")]
19use core::ptr;
20
21#[cfg(feature = "owning_ref")]
22use owning_ref::StableAddress;
23
24#[cfg(feature = "serde")]
25use 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.
36pub 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.
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.
52    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
65    unsafe fn unlock(&self);
66
67    /// Checks whether the mutex is currently locked.
68    #[inline]
69    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.
87pub 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
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
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.
120pub 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.
128    fn try_lock_for(&self, timeout: Self::Duration) -> bool;
129
130    /// Attempts to acquire this lock until a timeout is reached.
131    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.
142pub struct Mutex<R, T: ?Sized> {
143    raw: R,
144    data: UnsafeCell<T>,
145}
146
147unsafe impl<R: RawMutex + Send, T: ?Sized + Send> Send for Mutex<R, T> {}
148unsafe impl<R: RawMutex + Sync, T: ?Sized + Send> Sync for Mutex<R, T> {}
149
150impl<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]
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]
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]
173    pub fn into_inner(self) -> T {
174        self.data.into_inner()
175    }
176}
177
178impl<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]
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
191impl<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]
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]
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]
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]
246    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]
252    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]
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]
282    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]
298    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]
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]
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]
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
347impl<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]
360    pub unsafe fn force_unlock_fair(&self) {
361        self.raw.unlock_fair();
362    }
363}
364
365impl<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]
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]
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]
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]
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
430impl<R: RawMutex, T: ?Sized + Default> Default for Mutex<R, T> {
431    #[inline]
432    fn default() -> Mutex<R, T> {
433        Mutex::new(Default::default())
434    }
435}
436
437impl<R: RawMutex, T> From<T> for Mutex<R, T> {
438    #[inline]
439    fn from(t: T) -> Mutex<R, T> {
440        Mutex::new(t)
441    }
442}
443
444impl<R: RawMutex, T: ?Sized + fmt::Debug> fmt::Debug for Mutex<R, T> {
445    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")]
466impl<R, T> Serialize for Mutex<R, T>
467where
468    R: RawMutex,
469    T: Serialize + ?Sized,
470{
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")]
480impl<'de, R, T> Deserialize<'de> for Mutex<R, T>
481where
482    R: RawMutex,
483    T: Deserialize<'de> + ?Sized,
484{
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"]
500pub struct MutexGuard<'a, R: RawMutex, T: ?Sized> {
501    mutex: &'a Mutex<R, T>,
502    marker: PhantomData<(&'a mut T, R::GuardMarker)>,
503}
504
505unsafe impl<'a, R: RawMutex + Sync + 'a, T: ?Sized + Sync + 'a> Sync for MutexGuard<'a, R, T> {}
506
507impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> MutexGuard<'a, R, T> {
508    /// Returns a reference to the original `Mutex` object.
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]
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]
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]
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]
585    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
592impl<'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]
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]
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]
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
647impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Deref for MutexGuard<'a, R, T> {
648    type Target = T;
649    #[inline]
650    fn deref(&self) -> &T {
651        unsafe { &*self.mutex.data.get() }
652    }
653}
654
655impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> DerefMut for MutexGuard<'a, R, T> {
656    #[inline]
657    fn deref_mut(&mut self) -> &mut T {
658        unsafe { &mut *self.mutex.data.get() }
659    }
660}
661
662impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Drop for MutexGuard<'a, R, T> {
663    #[inline]
664    fn drop(&mut self) {
665        // Safety: A MutexGuard always holds the lock.
666        unsafe {
667            self.mutex.raw.unlock();
668        }
669    }
670}
671
672impl<'a, R: RawMutex + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for MutexGuard<'a, R, T> {
673    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
674        fmt::Debug::fmt(&**self, f)
675    }
676}
677
678impl<'a, R: RawMutex + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display for MutexGuard<'a, R, T> {
679    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
680        (**self).fmt(f)
681    }
682}
683
684#[cfg(feature = "owning_ref")]
685unsafe 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"]
694pub struct ArcMutexGuard<R: RawMutex, T: ?Sized> {
695    mutex: Arc<Mutex<R, T>>,
696    marker: PhantomData<*const ()>,
697}
698
699#[cfg(feature = "arc_lock")]
700unsafe 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")]
705unsafe 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")]
711impl<R: RawMutex, T: ?Sized> ArcMutexGuard<R, T> {
712    /// Returns a reference to the `Mutex` this is guarding, contained in its `Arc`.
713    #[inline]
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]
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]
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")]
749impl<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]
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]
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]
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")]
794impl<R: RawMutex, T: ?Sized> Deref for ArcMutexGuard<R, T> {
795    type Target = T;
796    #[inline]
797    fn deref(&self) -> &T {
798        unsafe { &*self.mutex.data.get() }
799    }
800}
801
802#[cfg(feature = "arc_lock")]
803impl<R: RawMutex, T: ?Sized> DerefMut for ArcMutexGuard<R, T> {
804    #[inline]
805    fn deref_mut(&mut self) -> &mut T {
806        unsafe { &mut *self.mutex.data.get() }
807    }
808}
809
810#[cfg(feature = "arc_lock")]
811impl<R: RawMutex, T: ?Sized> Drop for ArcMutexGuard<R, T> {
812    #[inline]
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"]
830pub struct MappedMutexGuard<'a, R: RawMutex, T: ?Sized> {
831    raw: &'a R,
832    data: *mut T,
833    marker: PhantomData<&'a mut T>,
834}
835
836unsafe impl<'a, R: RawMutex + Sync + 'a, T: ?Sized + Sync + 'a> Sync
837    for MappedMutexGuard<'a, R, T>
838{
839}
840unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + Send + 'a> Send for MappedMutexGuard<'a, R, T> where
841    R::GuardMarker: Send
842{
843}
844
845impl<'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]
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]
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
897impl<'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]
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
920impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Deref for MappedMutexGuard<'a, R, T> {
921    type Target = T;
922    #[inline]
923    fn deref(&self) -> &T {
924        unsafe { &*self.data }
925    }
926}
927
928impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> DerefMut for MappedMutexGuard<'a, R, T> {
929    #[inline]
930    fn deref_mut(&mut self) -> &mut T {
931        unsafe { &mut *self.data }
932    }
933}
934
935impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Drop for MappedMutexGuard<'a, R, T> {
936    #[inline]
937    fn drop(&mut self) {
938        // Safety: A MappedMutexGuard always holds the lock.
939        unsafe {
940            self.raw.unlock();
941        }
942    }
943}
944
945impl<'a, R: RawMutex + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for MappedMutexGuard<'a, R, T> {
946    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
947        fmt::Debug::fmt(&**self, f)
948    }
949}
950
951impl<'a, R: RawMutex + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display
952    for MappedMutexGuard<'a, R, T>
953{
954    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
955        (**self).fmt(f)
956    }
957}
958
959#[cfg(feature = "owning_ref")]
960unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> StableAddress for MappedMutexGuard<'a, R, T> {}