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`]: RawMutex::lock
62    /// [`try_lock`]: RawMutex::try_lock
63    /// [`try_lock_for`]: RawMutexTimed::try_lock_for
64    /// [`try_lock_until`]: RawMutexTimed::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`](RawMutex::unlock).
94    unsafe fn unlock_fair(&self);
95
96    /// Temporarily yields the mutex to a waiting thread if there is one.
97    ///
98    /// This method is functionally equivalent to calling `unlock_fair` followed
99    /// by `lock`, however it can be much more efficient in the case where there
100    /// are no waiting threads.
101    ///
102    /// # Safety
103    ///
104    /// This method may only be called if the mutex is held in the current context, see
105    /// the documentation of [`unlock`](RawMutex::unlock).
106    unsafe fn bump(&self) {
107        self.unlock_fair();
108        self.lock();
109    }
110}
111
112/// Additional methods for mutexes which support locking with timeouts.
113///
114/// The `Duration` and `Instant` types are specified as associated types so that
115/// this trait is usable even in `no_std` environments.
116pub unsafe trait RawMutexTimed: RawMutex {
117    /// Duration type used for `try_lock_for`.
118    type Duration;
119
120    /// Instant type used for `try_lock_until`.
121    type Instant;
122
123    /// Attempts to acquire this lock until a timeout is reached.
124    fn try_lock_for(&self, timeout: Self::Duration) -> bool;
125
126    /// Attempts to acquire this lock until a timeout is reached.
127    fn try_lock_until(&self, timeout: Self::Instant) -> bool;
128}
129
130/// A mutual exclusion primitive useful for protecting shared data
131///
132/// This mutex will block threads waiting for the lock to become available. The
133/// mutex can also be statically initialized or created via a `new`
134/// constructor. Each mutex has a type parameter which represents the data that
135/// it is protecting. The data can only be accessed through the RAII guards
136/// returned from `lock` and `try_lock`, which guarantees that the data is only
137/// ever accessed when the mutex is locked.
138pub struct Mutex<R, T: ?Sized> {
139    raw: R,
140    data: UnsafeCell<T>,
141}
142
143unsafe impl<R: RawMutex + Send, T: ?Sized + Send> Send for Mutex<R, T> {}
144unsafe impl<R: RawMutex + Sync, T: ?Sized + Send> Sync for Mutex<R, T> {}
145
146impl<R: RawMutex, T> Mutex<R, T> {
147    /// Creates a new mutex in an unlocked state ready for use.
148    #[inline]
149    pub const fn new(val: T) -> Mutex<R, T> {
150        Mutex {
151            raw: R::INIT,
152            data: UnsafeCell::new(val),
153        }
154    }
155
156    /// Consumes this mutex, returning the underlying data.
157    #[inline]
158    pub fn into_inner(self) -> T {
159        self.data.into_inner()
160    }
161}
162
163impl<R, T> Mutex<R, T> {
164    /// Creates a new mutex based on a pre-existing raw mutex.
165    #[inline]
166    pub const fn from_raw(raw_mutex: R, val: T) -> Mutex<R, T> {
167        Mutex {
168            raw: raw_mutex,
169            data: UnsafeCell::new(val),
170        }
171    }
172
173    /// Creates a new mutex based on a pre-existing raw mutex.
174    ///
175    /// This allows creating a mutex in a constant context on stable Rust.
176    ///
177    /// This method is a legacy alias for [`from_raw`](Self::from_raw).
178    #[inline]
179    pub const fn const_new(raw_mutex: R, val: T) -> Mutex<R, T> {
180        Self::from_raw(raw_mutex, val)
181    }
182}
183
184impl<R: RawMutex, T: ?Sized> Mutex<R, T> {
185    /// Creates a new `MutexGuard` without checking if the mutex is locked.
186    ///
187    /// # Safety
188    ///
189    /// This method must only be called if the thread logically holds the lock.
190    ///
191    /// Calling this function when a guard has already been produced is undefined behaviour unless
192    /// the guard was forgotten with `mem::forget`.
193    #[inline]
194    pub unsafe fn make_guard_unchecked(&self) -> MutexGuard<'_, R, T> {
195        MutexGuard {
196            mutex: self,
197            marker: PhantomData,
198        }
199    }
200
201    /// Acquires a mutex, blocking the current thread until it is able to do so.
202    ///
203    /// This function will block the local thread until it is available to acquire
204    /// the mutex. Upon returning, the thread is the only thread with the mutex
205    /// held. An RAII guard is returned to allow scoped unlock of the lock. When
206    /// the guard goes out of scope, the mutex will be unlocked.
207    ///
208    /// Attempts to lock a mutex in the thread which already holds the lock will
209    /// result in a deadlock.
210    #[inline]
211    #[track_caller]
212    pub fn lock(&self) -> MutexGuard<'_, R, T> {
213        self.raw.lock();
214        // SAFETY: The lock is held, as required.
215        unsafe { self.make_guard_unchecked() }
216    }
217
218    /// Attempts to acquire this lock.
219    ///
220    /// If the lock could not be acquired at this time, then `None` is returned.
221    /// Otherwise, an RAII guard is returned. The lock will be unlocked when the
222    /// guard is dropped.
223    ///
224    /// This function does not block.
225    #[inline]
226    #[track_caller]
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.make_guard_unchecked() })
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]
241    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]
247    #[track_caller]
248    pub fn is_locked(&self) -> bool {
249        self.raw.is_locked()
250    }
251
252    /// Forcibly unlocks the mutex.
253    ///
254    /// This is useful when combined with `mem::forget` to hold a lock without
255    /// the need to maintain a `MutexGuard` object alive, for example when
256    /// dealing with FFI.
257    ///
258    /// # Safety
259    ///
260    /// This method must only be called if the current thread logically owns a
261    /// `MutexGuard` but that guard has been discarded using `mem::forget`.
262    /// Behavior is undefined if a mutex is unlocked when not locked.
263    #[inline]
264    #[track_caller]
265    pub unsafe fn force_unlock(&self) {
266        self.raw.unlock();
267    }
268
269    /// Returns the underlying raw mutex object.
270    ///
271    /// Note that you will most likely need to import the `RawMutex` trait from
272    /// `lock_api` to be able to call functions on the raw mutex.
273    ///
274    /// # Safety
275    ///
276    /// This method is unsafe because it allows unlocking a mutex while
277    /// still holding a reference to a `MutexGuard`.
278    #[inline]
279    pub unsafe fn raw(&self) -> &R {
280        &self.raw
281    }
282
283    /// Returns a raw pointer to the underlying data.
284    ///
285    /// This is useful when combined with `mem::forget` to hold a lock without
286    /// the need to maintain a `MutexGuard` object alive, for example when
287    /// dealing with FFI.
288    ///
289    /// # Safety
290    ///
291    /// You must ensure that there are no data races when dereferencing the
292    /// returned pointer, for example if the current thread logically owns
293    /// a `MutexGuard` but that guard has been discarded using `mem::forget`.
294    #[inline]
295    pub fn data_ptr(&self) -> *mut T {
296        self.data.get()
297    }
298
299    /// Creates a new `ArcMutexGuard` without checking if the mutex is locked.
300    ///
301    /// # Safety
302    ///
303    /// This method must only be called if the thread logically holds the lock.
304    ///
305    /// Calling this function when a guard has already been produced is undefined behaviour unless
306    /// the guard was forgotten with `mem::forget`.
307    #[cfg(feature = "arc_lock")]
308    #[inline]
309    unsafe fn make_arc_guard_unchecked(self: &Arc<Self>) -> ArcMutexGuard<R, T> {
310        ArcMutexGuard {
311            mutex: self.clone(),
312            marker: PhantomData,
313        }
314    }
315
316    /// Acquires a lock through an `Arc`.
317    ///
318    /// This method is similar to the `lock` method; however, it requires the `Mutex` to be inside of an `Arc`
319    /// and the resulting mutex guard has no lifetime requirements.
320    #[cfg(feature = "arc_lock")]
321    #[inline]
322    #[track_caller]
323    pub fn lock_arc(self: &Arc<Self>) -> ArcMutexGuard<R, T> {
324        self.raw.lock();
325        // SAFETY: the locking guarantee is upheld
326        unsafe { self.make_arc_guard_unchecked() }
327    }
328
329    /// Attempts to acquire a lock through an `Arc`.
330    ///
331    /// This method is similar to the `try_lock` method; however, it requires the `Mutex` to be inside of an
332    /// `Arc` and the resulting mutex guard has no lifetime requirements.
333    #[cfg(feature = "arc_lock")]
334    #[inline]
335    #[track_caller]
336    pub fn try_lock_arc(self: &Arc<Self>) -> Option<ArcMutexGuard<R, T>> {
337        if self.raw.try_lock() {
338            // SAFETY: locking guarantee is upheld
339            Some(unsafe { self.make_arc_guard_unchecked() })
340        } else {
341            None
342        }
343    }
344}
345
346impl<R: RawMutexFair, T: ?Sized> Mutex<R, T> {
347    /// Forcibly unlocks the mutex using a fair unlock protocol.
348    ///
349    /// This is useful when combined with `mem::forget` to hold a lock without
350    /// the need to maintain a `MutexGuard` object alive, for example when
351    /// dealing with FFI.
352    ///
353    /// # Safety
354    ///
355    /// This method must only be called if the current thread logically owns a
356    /// `MutexGuard` but that guard has been discarded using `mem::forget`.
357    /// Behavior is undefined if a mutex is unlocked when not locked.
358    #[inline]
359    #[track_caller]
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    #[track_caller]
373    pub fn try_lock_for(&self, timeout: R::Duration) -> Option<MutexGuard<'_, R, T>> {
374        if self.raw.try_lock_for(timeout) {
375            // SAFETY: The lock is held, as required.
376            Some(unsafe { self.make_guard_unchecked() })
377        } else {
378            None
379        }
380    }
381
382    /// Attempts to acquire this lock until a timeout is reached.
383    ///
384    /// If the lock could not be acquired before the timeout expired, then
385    /// `None` is returned. Otherwise, an RAII guard is returned. The lock will
386    /// be unlocked when the guard is dropped.
387    #[inline]
388    #[track_caller]
389    pub fn try_lock_until(&self, timeout: R::Instant) -> Option<MutexGuard<'_, R, T>> {
390        if self.raw.try_lock_until(timeout) {
391            // SAFETY: The lock is held, as required.
392            Some(unsafe { self.make_guard_unchecked() })
393        } else {
394            None
395        }
396    }
397
398    /// Attempts to acquire this lock through an `Arc` until a timeout is reached.
399    ///
400    /// This method is similar to the `try_lock_for` method; however, it requires the `Mutex` to be inside of an
401    /// `Arc` and the resulting mutex guard has no lifetime requirements.
402    #[cfg(feature = "arc_lock")]
403    #[inline]
404    #[track_caller]
405    pub fn try_lock_arc_for(self: &Arc<Self>, timeout: R::Duration) -> Option<ArcMutexGuard<R, T>> {
406        if self.raw.try_lock_for(timeout) {
407            // SAFETY: locking guarantee is upheld
408            Some(unsafe { self.make_arc_guard_unchecked() })
409        } else {
410            None
411        }
412    }
413
414    /// Attempts to acquire this lock through an `Arc` until a timeout is reached.
415    ///
416    /// This method is similar to the `try_lock_until` method; however, it requires the `Mutex` to be inside of
417    /// an `Arc` and the resulting mutex guard has no lifetime requirements.
418    #[cfg(feature = "arc_lock")]
419    #[inline]
420    #[track_caller]
421    pub fn try_lock_arc_until(
422        self: &Arc<Self>,
423        timeout: R::Instant,
424    ) -> Option<ArcMutexGuard<R, T>> {
425        if self.raw.try_lock_until(timeout) {
426            // SAFETY: locking guarantee is upheld
427            Some(unsafe { self.make_arc_guard_unchecked() })
428        } else {
429            None
430        }
431    }
432}
433
434impl<R: RawMutex, T: ?Sized + Default> Default for Mutex<R, T> {
435    #[inline]
436    fn default() -> Mutex<R, T> {
437        Mutex::new(Default::default())
438    }
439}
440
441impl<R: RawMutex, T> From<T> for Mutex<R, T> {
442    #[inline]
443    fn from(t: T) -> Mutex<R, T> {
444        Mutex::new(t)
445    }
446}
447
448impl<R: RawMutex, T: ?Sized + fmt::Debug> fmt::Debug for Mutex<R, T> {
449    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
450        match self.try_lock() {
451            Some(guard) => f.debug_struct("Mutex").field("data", &&*guard).finish(),
452            None => {
453                struct LockedPlaceholder;
454                impl fmt::Debug for LockedPlaceholder {
455                    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
456                        f.write_str("<locked>")
457                    }
458                }
459
460                f.debug_struct("Mutex")
461                    .field("data", &LockedPlaceholder)
462                    .finish()
463            }
464        }
465    }
466}
467
468// Copied and modified from serde
469#[cfg(feature = "serde")]
470impl<R, T> Serialize for Mutex<R, T>
471where
472    R: RawMutex,
473    T: Serialize + ?Sized,
474{
475    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
476    where
477        S: Serializer,
478    {
479        self.lock().serialize(serializer)
480    }
481}
482
483#[cfg(feature = "serde")]
484impl<'de, R, T> Deserialize<'de> for Mutex<R, T>
485where
486    R: RawMutex,
487    T: Deserialize<'de> + ?Sized,
488{
489    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
490    where
491        D: Deserializer<'de>,
492    {
493        Deserialize::deserialize(deserializer).map(Mutex::new)
494    }
495}
496
497/// An RAII implementation of a "scoped lock" of a mutex. When this structure is
498/// dropped (falls out of scope), the lock will be unlocked.
499///
500/// The data protected by the mutex can be accessed through this guard via its
501/// `Deref` and `DerefMut` implementations.
502#[clippy::has_significant_drop]
503#[must_use = "if unused the Mutex will immediately unlock"]
504pub struct MutexGuard<'a, R: RawMutex, T: ?Sized> {
505    mutex: &'a Mutex<R, T>,
506    marker: PhantomData<(&'a mut T, R::GuardMarker)>,
507}
508
509unsafe impl<'a, R: RawMutex + Sync + 'a, T: ?Sized + Sync + 'a> Sync for MutexGuard<'a, R, T> {}
510
511impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> MutexGuard<'a, R, T> {
512    /// Returns a reference to the original `Mutex` object.
513    pub fn mutex(s: &Self) -> &'a Mutex<R, T> {
514        s.mutex
515    }
516
517    /// Makes a new `MappedMutexGuard` for a component of the locked data.
518    ///
519    /// This operation cannot fail as the `MutexGuard` passed
520    /// in already locked the mutex.
521    ///
522    /// This is an associated function that needs to be
523    /// used as `MutexGuard::map(...)`. A method would interfere with methods of
524    /// the same name on the contents of the locked data.
525    #[inline]
526    pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U>
527    where
528        F: FnOnce(&mut T) -> &mut U,
529    {
530        let raw = &s.mutex.raw;
531        let data = f(unsafe { &mut *s.mutex.data.get() });
532        mem::forget(s);
533        MappedMutexGuard {
534            raw,
535            data,
536            marker: PhantomData,
537        }
538    }
539
540    /// Attempts to make a new `MappedMutexGuard` for a component of the
541    /// locked data. The original guard is returned if the closure returns `None`.
542    ///
543    /// This operation cannot fail as the `MutexGuard` passed
544    /// in already locked the mutex.
545    ///
546    /// This is an associated function that needs to be
547    /// used as `MutexGuard::try_map(...)`. A method would interfere with methods of
548    /// the same name on the contents of the locked data.
549    #[inline]
550    pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self>
551    where
552        F: FnOnce(&mut T) -> Option<&mut U>,
553    {
554        let raw = &s.mutex.raw;
555        let data = match f(unsafe { &mut *s.mutex.data.get() }) {
556            Some(data) => data,
557            None => return Err(s),
558        };
559        mem::forget(s);
560        Ok(MappedMutexGuard {
561            raw,
562            data,
563            marker: PhantomData,
564        })
565    }
566
567    /// Attempts to make a new `MappedMutexGuard` for a component of the
568    /// locked data. The original guard is returned alongside arbitrary user data
569    /// if the closure returns `Err`.
570    ///
571    /// This operation cannot fail as the `MutexGuard` passed
572    /// in already locked the mutex.
573    ///
574    /// This is an associated function that needs to be
575    /// used as `MutexGuard::try_map_or_err(...)`. A method would interfere with methods of
576    /// the same name on the contents of the locked data.
577    #[inline]
578    pub fn try_map_or_err<U: ?Sized, F, E>(
579        s: Self,
580        f: F,
581    ) -> Result<MappedMutexGuard<'a, R, U>, (Self, E)>
582    where
583        F: FnOnce(&mut T) -> Result<&mut U, E>,
584    {
585        let raw = &s.mutex.raw;
586        let data = match f(unsafe { &mut *s.mutex.data.get() }) {
587            Ok(data) => data,
588            Err(e) => return Err((s, e)),
589        };
590        mem::forget(s);
591        Ok(MappedMutexGuard {
592            raw,
593            data,
594            marker: PhantomData,
595        })
596    }
597
598    /// Temporarily unlocks the mutex to execute the given function.
599    ///
600    /// This is safe because `&mut` guarantees that there exist no other
601    /// references to the data protected by the mutex.
602    #[inline]
603    #[track_caller]
604    pub fn unlocked<F, U>(s: &mut Self, f: F) -> U
605    where
606        F: FnOnce() -> U,
607    {
608        // Safety: A MutexGuard always holds the lock.
609        unsafe {
610            s.mutex.raw.unlock();
611        }
612        defer!(s.mutex.raw.lock());
613        f()
614    }
615
616    /// Leaks the mutex guard and returns a mutable reference to the data
617    /// protected by the mutex.
618    ///
619    /// This will leave the `Mutex` in a locked state.
620    #[inline]
621    pub fn leak(s: Self) -> &'a mut T {
622        let r = unsafe { &mut *s.mutex.data.get() };
623        mem::forget(s);
624        r
625    }
626}
627
628impl<'a, R: RawMutexFair + 'a, T: ?Sized + 'a> MutexGuard<'a, R, T> {
629    /// Unlocks the mutex using a fair unlock protocol.
630    ///
631    /// By default, mutexes are unfair and allow the current thread to re-lock
632    /// the mutex before another has the chance to acquire the lock, even if
633    /// that thread has been blocked on the mutex for a long time. This is the
634    /// default because it allows much higher throughput as it avoids forcing a
635    /// context switch on every mutex unlock. This can result in one thread
636    /// acquiring a mutex many more times than other threads.
637    ///
638    /// However in some cases it can be beneficial to ensure fairness by forcing
639    /// the lock to pass on to a waiting thread if there is one. This is done by
640    /// using this method instead of dropping the `MutexGuard` normally.
641    #[inline]
642    #[track_caller]
643    pub fn unlock_fair(s: Self) {
644        // Safety: A MutexGuard always holds the lock.
645        unsafe {
646            s.mutex.raw.unlock_fair();
647        }
648        mem::forget(s);
649    }
650
651    /// Temporarily unlocks the mutex to execute the given function.
652    ///
653    /// The mutex is unlocked using a fair unlock protocol.
654    ///
655    /// This is safe because `&mut` guarantees that there exist no other
656    /// references to the data protected by the mutex.
657    #[inline]
658    #[track_caller]
659    pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U
660    where
661        F: FnOnce() -> U,
662    {
663        // Safety: A MutexGuard always holds the lock.
664        unsafe {
665            s.mutex.raw.unlock_fair();
666        }
667        defer!(s.mutex.raw.lock());
668        f()
669    }
670
671    /// Temporarily yields the mutex to a waiting thread if there is one.
672    ///
673    /// This method is functionally equivalent to calling `unlock_fair` followed
674    /// by `lock`, however it can be much more efficient in the case where there
675    /// are no waiting threads.
676    #[inline]
677    #[track_caller]
678    pub fn bump(s: &mut Self) {
679        // Safety: A MutexGuard always holds the lock.
680        unsafe {
681            s.mutex.raw.bump();
682        }
683    }
684}
685
686impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Deref for MutexGuard<'a, R, T> {
687    type Target = T;
688    #[inline]
689    fn deref(&self) -> &T {
690        unsafe { &*self.mutex.data.get() }
691    }
692}
693
694impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> DerefMut for MutexGuard<'a, R, T> {
695    #[inline]
696    fn deref_mut(&mut self) -> &mut T {
697        unsafe { &mut *self.mutex.data.get() }
698    }
699}
700
701impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Drop for MutexGuard<'a, R, T> {
702    #[inline]
703    fn drop(&mut self) {
704        // Safety: A MutexGuard always holds the lock.
705        unsafe {
706            self.mutex.raw.unlock();
707        }
708    }
709}
710
711impl<'a, R: RawMutex + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for MutexGuard<'a, R, T> {
712    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
713        fmt::Debug::fmt(&**self, f)
714    }
715}
716
717impl<'a, R: RawMutex + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display for MutexGuard<'a, R, T> {
718    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
719        (**self).fmt(f)
720    }
721}
722
723#[cfg(feature = "owning_ref")]
724unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> StableAddress for MutexGuard<'a, R, T> {}
725
726/// An RAII mutex guard returned by the `Arc` locking operations on `Mutex`.
727///
728/// This is similar to the `MutexGuard` struct, except instead of using a reference to unlock the `Mutex` it
729/// uses an `Arc<Mutex>`. This has several advantages, most notably that it has an `'static` lifetime.
730#[cfg(feature = "arc_lock")]
731#[clippy::has_significant_drop]
732#[must_use = "if unused the Mutex will immediately unlock"]
733pub struct ArcMutexGuard<R: RawMutex, T: ?Sized> {
734    mutex: Arc<Mutex<R, T>>,
735    marker: PhantomData<*const ()>,
736}
737
738#[cfg(feature = "arc_lock")]
739unsafe impl<R: RawMutex + Send + Sync, T: Send + ?Sized> Send for ArcMutexGuard<R, T> where
740    R::GuardMarker: Send
741{
742}
743#[cfg(feature = "arc_lock")]
744unsafe impl<R: RawMutex + Sync, T: Sync + ?Sized> Sync for ArcMutexGuard<R, T> where
745    R::GuardMarker: Sync
746{
747}
748
749#[cfg(feature = "arc_lock")]
750impl<R: RawMutex, T: ?Sized> ArcMutexGuard<R, T> {
751    /// Returns a reference to the `Mutex` this is guarding, contained in its `Arc`.
752    #[inline]
753    pub fn mutex(s: &Self) -> &Arc<Mutex<R, T>> {
754        &s.mutex
755    }
756
757    /// Unlocks the mutex and returns the `Arc` that was held by the [`ArcMutexGuard`].
758    #[inline]
759    #[track_caller]
760    pub fn into_arc(s: Self) -> Arc<Mutex<R, T>> {
761        // SAFETY: Skip our Drop impl and manually unlock the mutex.
762        let s = ManuallyDrop::new(s);
763        unsafe {
764            s.mutex.raw.unlock();
765            ptr::read(&s.mutex)
766        }
767    }
768
769    /// Temporarily unlocks the mutex to execute the given function.
770    ///
771    /// This is safe because `&mut` guarantees that there exist no other
772    /// references to the data protected by the mutex.
773    #[inline]
774    #[track_caller]
775    pub fn unlocked<F, U>(s: &mut Self, f: F) -> U
776    where
777        F: FnOnce() -> U,
778    {
779        // Safety: A MutexGuard always holds the lock.
780        unsafe {
781            s.mutex.raw.unlock();
782        }
783        defer!(s.mutex.raw.lock());
784        f()
785    }
786}
787
788#[cfg(feature = "arc_lock")]
789impl<R: RawMutexFair, T: ?Sized> ArcMutexGuard<R, T> {
790    /// Unlocks the mutex using a fair unlock protocol.
791    ///
792    /// This is functionally identical to the `unlock_fair` method on [`MutexGuard`].
793    #[inline]
794    #[track_caller]
795    pub fn unlock_fair(s: Self) {
796        drop(Self::into_arc_fair(s));
797    }
798
799    /// Unlocks the mutex using a fair unlock protocol and returns the `Arc` that was held by the [`ArcMutexGuard`].
800    #[inline]
801    pub fn into_arc_fair(s: Self) -> Arc<Mutex<R, T>> {
802        // SAFETY: Skip our Drop impl and manually unlock the mutex.
803        let s = ManuallyDrop::new(s);
804        unsafe {
805            s.mutex.raw.unlock_fair();
806            ptr::read(&s.mutex)
807        }
808    }
809
810    /// Temporarily unlocks the mutex to execute the given function.
811    ///
812    /// This is functionally identical to the `unlocked_fair` method on [`MutexGuard`].
813    #[inline]
814    #[track_caller]
815    pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U
816    where
817        F: FnOnce() -> U,
818    {
819        // Safety: A MutexGuard always holds the lock.
820        unsafe {
821            s.mutex.raw.unlock_fair();
822        }
823        defer!(s.mutex.raw.lock());
824        f()
825    }
826
827    /// Temporarily yields the mutex to a waiting thread if there is one.
828    ///
829    /// This is functionally identical to the `bump` method on [`MutexGuard`].
830    #[inline]
831    #[track_caller]
832    pub fn bump(s: &mut Self) {
833        // Safety: A MutexGuard always holds the lock.
834        unsafe {
835            s.mutex.raw.bump();
836        }
837    }
838}
839
840#[cfg(feature = "arc_lock")]
841impl<R: RawMutex, T: ?Sized> Deref for ArcMutexGuard<R, T> {
842    type Target = T;
843    #[inline]
844    fn deref(&self) -> &T {
845        unsafe { &*self.mutex.data.get() }
846    }
847}
848
849#[cfg(feature = "arc_lock")]
850impl<R: RawMutex, T: ?Sized> DerefMut for ArcMutexGuard<R, T> {
851    #[inline]
852    fn deref_mut(&mut self) -> &mut T {
853        unsafe { &mut *self.mutex.data.get() }
854    }
855}
856
857#[cfg(feature = "arc_lock")]
858impl<R: RawMutex, T: ?Sized> Drop for ArcMutexGuard<R, T> {
859    #[inline]
860    fn drop(&mut self) {
861        // Safety: A MutexGuard always holds the lock.
862        unsafe {
863            self.mutex.raw.unlock();
864        }
865    }
866}
867
868/// An RAII mutex guard returned by `MutexGuard::map`, which can point to a
869/// subfield of the protected data.
870///
871/// The main difference between `MappedMutexGuard` and `MutexGuard` is that the
872/// former doesn't support temporarily unlocking and re-locking, since that
873/// could introduce soundness issues if the locked object is modified by another
874/// thread.
875#[clippy::has_significant_drop]
876#[must_use = "if unused the Mutex will immediately unlock"]
877pub struct MappedMutexGuard<'a, R: RawMutex, T: ?Sized> {
878    raw: &'a R,
879    data: *mut T,
880    marker: PhantomData<&'a mut T>,
881}
882
883unsafe impl<'a, R: RawMutex + Sync + 'a, T: ?Sized + Sync + 'a> Sync
884    for MappedMutexGuard<'a, R, T>
885{
886}
887unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + Send + 'a> Send for MappedMutexGuard<'a, R, T> where
888    R::GuardMarker: Send
889{
890}
891
892impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> MappedMutexGuard<'a, R, T> {
893    /// Makes a new `MappedMutexGuard` for a component of the locked data.
894    ///
895    /// This operation cannot fail as the `MappedMutexGuard` passed
896    /// in already locked the mutex.
897    ///
898    /// This is an associated function that needs to be
899    /// used as `MappedMutexGuard::map(...)`. A method would interfere with methods of
900    /// the same name on the contents of the locked data.
901    #[inline]
902    pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U>
903    where
904        F: FnOnce(&mut T) -> &mut U,
905    {
906        let raw = s.raw;
907        let data = f(unsafe { &mut *s.data });
908        mem::forget(s);
909        MappedMutexGuard {
910            raw,
911            data,
912            marker: PhantomData,
913        }
914    }
915
916    /// Attempts to make a new `MappedMutexGuard` for a component of the
917    /// locked data. The original guard is returned if the closure returns `None`.
918    ///
919    /// This operation cannot fail as the `MappedMutexGuard` passed
920    /// in already locked the mutex.
921    ///
922    /// This is an associated function that needs to be
923    /// used as `MappedMutexGuard::try_map(...)`. A method would interfere with methods of
924    /// the same name on the contents of the locked data.
925    #[inline]
926    pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self>
927    where
928        F: FnOnce(&mut T) -> Option<&mut U>,
929    {
930        let raw = s.raw;
931        let data = match f(unsafe { &mut *s.data }) {
932            Some(data) => data,
933            None => return Err(s),
934        };
935        mem::forget(s);
936        Ok(MappedMutexGuard {
937            raw,
938            data,
939            marker: PhantomData,
940        })
941    }
942
943    /// Attempts to make a new `MappedMutexGuard` for a component of the
944    /// locked data. The original guard is returned alongside arbitrary user data
945    /// if the closure returns `Err`.
946    ///
947    /// This operation cannot fail as the `MappedMutexGuard` passed
948    /// in already locked the mutex.
949    ///
950    /// This is an associated function that needs to be
951    /// used as `MappedMutexGuard::try_map_or_err(...)`. A method would interfere with methods of
952    /// the same name on the contents of the locked data.
953    #[inline]
954    pub fn try_map_or_err<U: ?Sized, F, E>(
955        s: Self,
956        f: F,
957    ) -> Result<MappedMutexGuard<'a, R, U>, (Self, E)>
958    where
959        F: FnOnce(&mut T) -> Result<&mut U, E>,
960    {
961        let raw = s.raw;
962        let data = match f(unsafe { &mut *s.data }) {
963            Ok(data) => data,
964            Err(e) => return Err((s, e)),
965        };
966        mem::forget(s);
967        Ok(MappedMutexGuard {
968            raw,
969            data,
970            marker: PhantomData,
971        })
972    }
973}
974
975impl<'a, R: RawMutexFair + 'a, T: ?Sized + 'a> MappedMutexGuard<'a, R, T> {
976    /// Unlocks the mutex using a fair unlock protocol.
977    ///
978    /// By default, mutexes are unfair and allow the current thread to re-lock
979    /// the mutex before another has the chance to acquire the lock, even if
980    /// that thread has been blocked on the mutex for a long time. This is the
981    /// default because it allows much higher throughput as it avoids forcing a
982    /// context switch on every mutex unlock. This can result in one thread
983    /// acquiring a mutex many more times than other threads.
984    ///
985    /// However in some cases it can be beneficial to ensure fairness by forcing
986    /// the lock to pass on to a waiting thread if there is one. This is done by
987    /// using this method instead of dropping the `MutexGuard` normally.
988    #[inline]
989    #[track_caller]
990    pub fn unlock_fair(s: Self) {
991        // Safety: A MutexGuard always holds the lock.
992        unsafe {
993            s.raw.unlock_fair();
994        }
995        mem::forget(s);
996    }
997}
998
999impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Deref for MappedMutexGuard<'a, R, T> {
1000    type Target = T;
1001    #[inline]
1002    fn deref(&self) -> &T {
1003        unsafe { &*self.data }
1004    }
1005}
1006
1007impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> DerefMut for MappedMutexGuard<'a, R, T> {
1008    #[inline]
1009    fn deref_mut(&mut self) -> &mut T {
1010        unsafe { &mut *self.data }
1011    }
1012}
1013
1014impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Drop for MappedMutexGuard<'a, R, T> {
1015    #[inline]
1016    fn drop(&mut self) {
1017        // Safety: A MappedMutexGuard always holds the lock.
1018        unsafe {
1019            self.raw.unlock();
1020        }
1021    }
1022}
1023
1024impl<'a, R: RawMutex + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for MappedMutexGuard<'a, R, T> {
1025    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1026        fmt::Debug::fmt(&**self, f)
1027    }
1028}
1029
1030impl<'a, R: RawMutex + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display
1031    for MappedMutexGuard<'a, R, T>
1032{
1033    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1034        (**self).fmt(f)
1035    }
1036}
1037
1038#[cfg(feature = "owning_ref")]
1039unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> StableAddress for MappedMutexGuard<'a, R, T> {}