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 = "owning_ref")]
15 use owning_ref::StableAddress;
16 
17 #[cfg(feature = "serde")]
18 use serde::{Deserialize, Deserializer, Serialize, Serializer};
19 
20 /// Basic operations for a mutex.
21 ///
22 /// Types implementing this trait can be used by `Mutex` to form a safe and
23 /// fully-functioning mutex type.
24 ///
25 /// # Safety
26 ///
27 /// Implementations of this trait must ensure that the mutex is actually
28 /// exclusive: a lock can't be acquired while the mutex is already locked.
29 pub unsafe trait RawMutex {
30     /// Initial value for an unlocked mutex.
31     // A “non-constant” const item is a legacy way to supply an initialized value to downstream
32     // static items. Can hopefully be replaced with `const fn new() -> Self` at some point.
33     #[allow(clippy::declare_interior_mutable_const)]
34     const INIT: Self;
35 
36     /// Marker type which determines whether a lock guard should be `Send`. Use
37     /// one of the `GuardSend` or `GuardNoSend` helper types here.
38     type GuardMarker;
39 
40     /// Acquires this mutex, blocking the current thread until it is able to do so.
lock(&self)41     fn lock(&self);
42 
43     /// Attempts to acquire this mutex without blocking. Returns `true`
44     /// if the lock was successfully acquired and `false` otherwise.
try_lock(&self) -> bool45     fn try_lock(&self) -> bool;
46 
47     /// Unlocks this mutex.
48     ///
49     /// # Safety
50     ///
51     /// This method may only be called if the mutex is held in the current context, i.e. it must
52     /// be paired with a successful call to [`lock`], [`try_lock`], [`try_lock_for`] or [`try_lock_until`].
53     ///
54     /// [`lock`]: #tymethod.lock
55     /// [`try_lock`]: #tymethod.try_lock
56     /// [`try_lock_for`]: trait.RawMutexTimed.html#tymethod.try_lock_for
57     /// [`try_lock_until`]: trait.RawMutexTimed.html#tymethod.try_lock_until
unlock(&self)58     unsafe fn unlock(&self);
59 
60     /// Checks whether the mutex is currently locked.
61     #[inline]
is_locked(&self) -> bool62     fn is_locked(&self) -> bool {
63         let acquired_lock = self.try_lock();
64         if acquired_lock {
65             // Safety: The lock has been successfully acquired above.
66             unsafe {
67                 self.unlock();
68             }
69         }
70         !acquired_lock
71     }
72 }
73 
74 /// Additional methods for mutexes which support fair unlocking.
75 ///
76 /// Fair unlocking means that a lock is handed directly over to the next waiting
77 /// thread if there is one, without giving other threads the opportunity to
78 /// "steal" the lock in the meantime. This is typically slower than unfair
79 /// unlocking, but may be necessary in certain circumstances.
80 pub unsafe trait RawMutexFair: RawMutex {
81     /// Unlocks this mutex using a fair unlock protocol.
82     ///
83     /// # Safety
84     ///
85     /// This method may only be called if the mutex is held in the current context, see
86     /// the documentation of [`unlock`].
87     ///
88     /// [`unlock`]: trait.RawMutex.html#tymethod.unlock
unlock_fair(&self)89     unsafe fn unlock_fair(&self);
90 
91     /// Temporarily yields the mutex to a waiting thread if there is one.
92     ///
93     /// This method is functionally equivalent to calling `unlock_fair` followed
94     /// by `lock`, however it can be much more efficient in the case where there
95     /// are no waiting threads.
96     ///
97     /// # Safety
98     ///
99     /// This method may only be called if the mutex is held in the current context, see
100     /// the documentation of [`unlock`].
101     ///
102     /// [`unlock`]: trait.RawMutex.html#tymethod.unlock
bump(&self)103     unsafe fn bump(&self) {
104         self.unlock_fair();
105         self.lock();
106     }
107 }
108 
109 /// Additional methods for mutexes which support locking with timeouts.
110 ///
111 /// The `Duration` and `Instant` types are specified as associated types so that
112 /// this trait is usable even in `no_std` environments.
113 pub unsafe trait RawMutexTimed: RawMutex {
114     /// Duration type used for `try_lock_for`.
115     type Duration;
116 
117     /// Instant type used for `try_lock_until`.
118     type Instant;
119 
120     /// Attempts to acquire this lock until a timeout is reached.
try_lock_for(&self, timeout: Self::Duration) -> bool121     fn try_lock_for(&self, timeout: Self::Duration) -> bool;
122 
123     /// Attempts to acquire this lock until a timeout is reached.
try_lock_until(&self, timeout: Self::Instant) -> bool124     fn try_lock_until(&self, timeout: Self::Instant) -> bool;
125 }
126 
127 /// A mutual exclusion primitive useful for protecting shared data
128 ///
129 /// This mutex will block threads waiting for the lock to become available. The
130 /// mutex can also be statically initialized or created via a `new`
131 /// constructor. Each mutex has a type parameter which represents the data that
132 /// it is protecting. The data can only be accessed through the RAII guards
133 /// returned from `lock` and `try_lock`, which guarantees that the data is only
134 /// ever accessed when the mutex is locked.
135 pub struct Mutex<R, T: ?Sized> {
136     raw: R,
137     data: UnsafeCell<T>,
138 }
139 
140 unsafe impl<R: RawMutex + Send, T: ?Sized + Send> Send for Mutex<R, T> {}
141 unsafe impl<R: RawMutex + Sync, T: ?Sized + Send> Sync for Mutex<R, T> {}
142 
143 impl<R: RawMutex, T> Mutex<R, T> {
144     /// Creates a new mutex in an unlocked state ready for use.
145     #[cfg(feature = "nightly")]
146     #[inline]
new(val: T) -> Mutex<R, T>147     pub const fn new(val: T) -> Mutex<R, T> {
148         Mutex {
149             raw: R::INIT,
150             data: UnsafeCell::new(val),
151         }
152     }
153 
154     /// Creates a new mutex in an unlocked state ready for use.
155     #[cfg(not(feature = "nightly"))]
156     #[inline]
new(val: T) -> Mutex<R, T>157     pub fn new(val: T) -> Mutex<R, T> {
158         Mutex {
159             raw: R::INIT,
160             data: UnsafeCell::new(val),
161         }
162     }
163 
164     /// Consumes this mutex, returning the underlying data.
165     #[inline]
into_inner(self) -> T166     pub fn into_inner(self) -> T {
167         self.data.into_inner()
168     }
169 }
170 
171 impl<R, T> Mutex<R, T> {
172     /// Creates a new mutex based on a pre-existing raw mutex.
173     ///
174     /// This allows creating a mutex in a constant context on stable Rust.
175     #[inline]
const_new(raw_mutex: R, val: T) -> Mutex<R, T>176     pub const fn const_new(raw_mutex: R, val: T) -> Mutex<R, T> {
177         Mutex {
178             raw: raw_mutex,
179             data: UnsafeCell::new(val),
180         }
181     }
182 }
183 
184 impl<R: RawMutex, T: ?Sized> Mutex<R, T> {
185     /// # Safety
186     ///
187     /// The lock must be held when calling this method.
188     #[inline]
guard(&self) -> MutexGuard<'_, R, T>189     unsafe fn guard(&self) -> MutexGuard<'_, R, T> {
190         MutexGuard {
191             mutex: self,
192             marker: PhantomData,
193         }
194     }
195 
196     /// Acquires a mutex, blocking the current thread until it is able to do so.
197     ///
198     /// This function will block the local thread until it is available to acquire
199     /// the mutex. Upon returning, the thread is the only thread with the mutex
200     /// held. An RAII guard is returned to allow scoped unlock of the lock. When
201     /// the guard goes out of scope, the mutex will be unlocked.
202     ///
203     /// Attempts to lock a mutex in the thread which already holds the lock will
204     /// result in a deadlock.
205     #[inline]
lock(&self) -> MutexGuard<'_, R, T>206     pub fn lock(&self) -> MutexGuard<'_, R, T> {
207         self.raw.lock();
208         // SAFETY: The lock is held, as required.
209         unsafe { self.guard() }
210     }
211 
212     /// Attempts to acquire this lock.
213     ///
214     /// If the lock could not be acquired at this time, then `None` is returned.
215     /// Otherwise, an RAII guard is returned. The lock will be unlocked when the
216     /// guard is dropped.
217     ///
218     /// This function does not block.
219     #[inline]
try_lock(&self) -> Option<MutexGuard<'_, R, T>>220     pub fn try_lock(&self) -> Option<MutexGuard<'_, R, T>> {
221         if self.raw.try_lock() {
222             // SAFETY: The lock is held, as required.
223             Some(unsafe { self.guard() })
224         } else {
225             None
226         }
227     }
228 
229     /// Returns a mutable reference to the underlying data.
230     ///
231     /// Since this call borrows the `Mutex` mutably, no actual locking needs to
232     /// take place---the mutable borrow statically guarantees no locks exist.
233     #[inline]
get_mut(&mut self) -> &mut T234     pub fn get_mut(&mut self) -> &mut T {
235         unsafe { &mut *self.data.get() }
236     }
237 
238     /// Checks whether the mutex is currently locked.
239     #[inline]
is_locked(&self) -> bool240     pub fn is_locked(&self) -> bool {
241         self.raw.is_locked()
242     }
243 
244     /// Forcibly unlocks the mutex.
245     ///
246     /// This is useful when combined with `mem::forget` to hold a lock without
247     /// the need to maintain a `MutexGuard` object alive, for example when
248     /// dealing with FFI.
249     ///
250     /// # Safety
251     ///
252     /// This method must only be called if the current thread logically owns a
253     /// `MutexGuard` but that guard has be discarded using `mem::forget`.
254     /// Behavior is undefined if a mutex is unlocked when not locked.
255     #[inline]
force_unlock(&self)256     pub unsafe fn force_unlock(&self) {
257         self.raw.unlock();
258     }
259 
260     /// Returns the underlying raw mutex object.
261     ///
262     /// Note that you will most likely need to import the `RawMutex` trait from
263     /// `lock_api` to be able to call functions on the raw mutex.
264     ///
265     /// # Safety
266     ///
267     /// This method is unsafe because it allows unlocking a mutex while
268     /// still holding a reference to a `MutexGuard`.
269     #[inline]
raw(&self) -> &R270     pub unsafe fn raw(&self) -> &R {
271         &self.raw
272     }
273 
274     /// Returns a raw pointer to the underlying data.
275     ///
276     /// This is useful when combined with `mem::forget` to hold a lock without
277     /// the need to maintain a `MutexGuard` object alive, for example when
278     /// dealing with FFI.
279     ///
280     /// # Safety
281     ///
282     /// You must ensure that there are no data races when dereferencing the
283     /// returned pointer, for example if the current thread logically owns
284     /// a `MutexGuard` but that guard has been discarded using `mem::forget`.
285     #[inline]
data_ptr(&self) -> *mut T286     pub fn data_ptr(&self) -> *mut T {
287         self.data.get()
288     }
289 }
290 
291 impl<R: RawMutexFair, T: ?Sized> Mutex<R, T> {
292     /// Forcibly unlocks the mutex using a fair unlock procotol.
293     ///
294     /// This is useful when combined with `mem::forget` to hold a lock without
295     /// the need to maintain a `MutexGuard` object alive, for example when
296     /// dealing with FFI.
297     ///
298     /// # Safety
299     ///
300     /// This method must only be called if the current thread logically owns a
301     /// `MutexGuard` but that guard has be discarded using `mem::forget`.
302     /// Behavior is undefined if a mutex is unlocked when not locked.
303     #[inline]
force_unlock_fair(&self)304     pub unsafe fn force_unlock_fair(&self) {
305         self.raw.unlock_fair();
306     }
307 }
308 
309 impl<R: RawMutexTimed, T: ?Sized> Mutex<R, T> {
310     /// Attempts to acquire this lock until a timeout is reached.
311     ///
312     /// If the lock could not be acquired before the timeout expired, then
313     /// `None` is returned. Otherwise, an RAII guard is returned. The lock will
314     /// be unlocked when the guard is dropped.
315     #[inline]
try_lock_for(&self, timeout: R::Duration) -> Option<MutexGuard<'_, R, T>>316     pub fn try_lock_for(&self, timeout: R::Duration) -> Option<MutexGuard<'_, R, T>> {
317         if self.raw.try_lock_for(timeout) {
318             // SAFETY: The lock is held, as required.
319             Some(unsafe { self.guard() })
320         } else {
321             None
322         }
323     }
324 
325     /// Attempts to acquire this lock until a timeout is reached.
326     ///
327     /// If the lock could not be acquired before the timeout expired, then
328     /// `None` is returned. Otherwise, an RAII guard is returned. The lock will
329     /// be unlocked when the guard is dropped.
330     #[inline]
try_lock_until(&self, timeout: R::Instant) -> Option<MutexGuard<'_, R, T>>331     pub fn try_lock_until(&self, timeout: R::Instant) -> Option<MutexGuard<'_, R, T>> {
332         if self.raw.try_lock_until(timeout) {
333             // SAFETY: The lock is held, as required.
334             Some(unsafe { self.guard() })
335         } else {
336             None
337         }
338     }
339 }
340 
341 impl<R: RawMutex, T: ?Sized + Default> Default for Mutex<R, T> {
342     #[inline]
default() -> Mutex<R, T>343     fn default() -> Mutex<R, T> {
344         Mutex::new(Default::default())
345     }
346 }
347 
348 impl<R: RawMutex, T> From<T> for Mutex<R, T> {
349     #[inline]
from(t: T) -> Mutex<R, T>350     fn from(t: T) -> Mutex<R, T> {
351         Mutex::new(t)
352     }
353 }
354 
355 impl<R: RawMutex, T: ?Sized + fmt::Debug> fmt::Debug for Mutex<R, T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result356     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
357         match self.try_lock() {
358             Some(guard) => f.debug_struct("Mutex").field("data", &&*guard).finish(),
359             None => {
360                 struct LockedPlaceholder;
361                 impl fmt::Debug for LockedPlaceholder {
362                     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
363                         f.write_str("<locked>")
364                     }
365                 }
366 
367                 f.debug_struct("Mutex")
368                     .field("data", &LockedPlaceholder)
369                     .finish()
370             }
371         }
372     }
373 }
374 
375 // Copied and modified from serde
376 #[cfg(feature = "serde")]
377 impl<R, T> Serialize for Mutex<R, T>
378 where
379     R: RawMutex,
380     T: Serialize + ?Sized,
381 {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,382     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
383     where
384         S: Serializer,
385     {
386         self.lock().serialize(serializer)
387     }
388 }
389 
390 #[cfg(feature = "serde")]
391 impl<'de, R, T> Deserialize<'de> for Mutex<R, T>
392 where
393     R: RawMutex,
394     T: Deserialize<'de> + ?Sized,
395 {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,396     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
397     where
398         D: Deserializer<'de>,
399     {
400         Deserialize::deserialize(deserializer).map(Mutex::new)
401     }
402 }
403 
404 /// An RAII implementation of a "scoped lock" of a mutex. When this structure is
405 /// dropped (falls out of scope), the lock will be unlocked.
406 ///
407 /// The data protected by the mutex can be accessed through this guard via its
408 /// `Deref` and `DerefMut` implementations.
409 #[must_use = "if unused the Mutex will immediately unlock"]
410 pub struct MutexGuard<'a, R: RawMutex, T: ?Sized> {
411     mutex: &'a Mutex<R, T>,
412     marker: PhantomData<(&'a mut T, R::GuardMarker)>,
413 }
414 
415 unsafe impl<'a, R: RawMutex + Sync + 'a, T: ?Sized + Sync + 'a> Sync for MutexGuard<'a, R, T> {}
416 
417 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> MutexGuard<'a, R, T> {
418     /// Returns a reference to the original `Mutex` object.
mutex(s: &Self) -> &'a Mutex<R, T>419     pub fn mutex(s: &Self) -> &'a Mutex<R, T> {
420         s.mutex
421     }
422 
423     /// Makes a new `MappedMutexGuard` for a component of the locked data.
424     ///
425     /// This operation cannot fail as the `MutexGuard` passed
426     /// in already locked the mutex.
427     ///
428     /// This is an associated function that needs to be
429     /// used as `MutexGuard::map(...)`. A method would interfere with methods of
430     /// the same name on the contents of the locked data.
431     #[inline]
map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U> where F: FnOnce(&mut T) -> &mut U,432     pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U>
433     where
434         F: FnOnce(&mut T) -> &mut U,
435     {
436         let raw = &s.mutex.raw;
437         let data = f(unsafe { &mut *s.mutex.data.get() });
438         mem::forget(s);
439         MappedMutexGuard {
440             raw,
441             data,
442             marker: PhantomData,
443         }
444     }
445 
446     /// Attempts to make a new `MappedMutexGuard` for a component of the
447     /// locked data. The original guard is returned if the closure returns `None`.
448     ///
449     /// This operation cannot fail as the `MutexGuard` passed
450     /// in already locked the mutex.
451     ///
452     /// This is an associated function that needs to be
453     /// used as `MutexGuard::try_map(...)`. A method would interfere with methods of
454     /// the same name on the contents of the locked data.
455     #[inline]
try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self> where F: FnOnce(&mut T) -> Option<&mut U>,456     pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self>
457     where
458         F: FnOnce(&mut T) -> Option<&mut U>,
459     {
460         let raw = &s.mutex.raw;
461         let data = match f(unsafe { &mut *s.mutex.data.get() }) {
462             Some(data) => data,
463             None => return Err(s),
464         };
465         mem::forget(s);
466         Ok(MappedMutexGuard {
467             raw,
468             data,
469             marker: PhantomData,
470         })
471     }
472 
473     /// Temporarily unlocks the mutex to execute the given function.
474     ///
475     /// This is safe because `&mut` guarantees that there exist no other
476     /// references to the data protected by the mutex.
477     #[inline]
unlocked<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,478     pub fn unlocked<F, U>(s: &mut Self, f: F) -> U
479     where
480         F: FnOnce() -> U,
481     {
482         // Safety: A MutexGuard always holds the lock.
483         unsafe {
484             s.mutex.raw.unlock();
485         }
486         defer!(s.mutex.raw.lock());
487         f()
488     }
489 }
490 
491 impl<'a, R: RawMutexFair + 'a, T: ?Sized + 'a> MutexGuard<'a, R, T> {
492     /// Unlocks the mutex using a fair unlock protocol.
493     ///
494     /// By default, mutexes are unfair and allow the current thread to re-lock
495     /// the mutex before another has the chance to acquire the lock, even if
496     /// that thread has been blocked on the mutex for a long time. This is the
497     /// default because it allows much higher throughput as it avoids forcing a
498     /// context switch on every mutex unlock. This can result in one thread
499     /// acquiring a mutex many more times than other threads.
500     ///
501     /// However in some cases it can be beneficial to ensure fairness by forcing
502     /// the lock to pass on to a waiting thread if there is one. This is done by
503     /// using this method instead of dropping the `MutexGuard` normally.
504     #[inline]
unlock_fair(s: Self)505     pub fn unlock_fair(s: Self) {
506         // Safety: A MutexGuard always holds the lock.
507         unsafe {
508             s.mutex.raw.unlock_fair();
509         }
510         mem::forget(s);
511     }
512 
513     /// Temporarily unlocks the mutex to execute the given function.
514     ///
515     /// The mutex is unlocked using a fair unlock protocol.
516     ///
517     /// This is safe because `&mut` guarantees that there exist no other
518     /// references to the data protected by the mutex.
519     #[inline]
unlocked_fair<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U,520     pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U
521     where
522         F: FnOnce() -> U,
523     {
524         // Safety: A MutexGuard always holds the lock.
525         unsafe {
526             s.mutex.raw.unlock_fair();
527         }
528         defer!(s.mutex.raw.lock());
529         f()
530     }
531 
532     /// Temporarily yields the mutex to a waiting thread if there is one.
533     ///
534     /// This method is functionally equivalent to calling `unlock_fair` followed
535     /// by `lock`, however it can be much more efficient in the case where there
536     /// are no waiting threads.
537     #[inline]
bump(s: &mut Self)538     pub fn bump(s: &mut Self) {
539         // Safety: A MutexGuard always holds the lock.
540         unsafe {
541             s.mutex.raw.bump();
542         }
543     }
544 }
545 
546 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Deref for MutexGuard<'a, R, T> {
547     type Target = T;
548     #[inline]
deref(&self) -> &T549     fn deref(&self) -> &T {
550         unsafe { &*self.mutex.data.get() }
551     }
552 }
553 
554 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> DerefMut for MutexGuard<'a, R, T> {
555     #[inline]
deref_mut(&mut self) -> &mut T556     fn deref_mut(&mut self) -> &mut T {
557         unsafe { &mut *self.mutex.data.get() }
558     }
559 }
560 
561 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Drop for MutexGuard<'a, R, T> {
562     #[inline]
drop(&mut self)563     fn drop(&mut self) {
564         // Safety: A MutexGuard always holds the lock.
565         unsafe {
566             self.mutex.raw.unlock();
567         }
568     }
569 }
570 
571 impl<'a, R: RawMutex + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for MutexGuard<'a, R, T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result572     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
573         fmt::Debug::fmt(&**self, f)
574     }
575 }
576 
577 impl<'a, R: RawMutex + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display for MutexGuard<'a, R, T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result578     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
579         (**self).fmt(f)
580     }
581 }
582 
583 #[cfg(feature = "owning_ref")]
584 unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> StableAddress for MutexGuard<'a, R, T> {}
585 
586 /// An RAII mutex guard returned by `MutexGuard::map`, which can point to a
587 /// subfield of the protected data.
588 ///
589 /// The main difference between `MappedMutexGuard` and `MutexGuard` is that the
590 /// former doesn't support temporarily unlocking and re-locking, since that
591 /// could introduce soundness issues if the locked object is modified by another
592 /// thread.
593 #[must_use = "if unused the Mutex will immediately unlock"]
594 pub struct MappedMutexGuard<'a, R: RawMutex, T: ?Sized> {
595     raw: &'a R,
596     data: *mut T,
597     marker: PhantomData<&'a mut T>,
598 }
599 
600 unsafe impl<'a, R: RawMutex + Sync + 'a, T: ?Sized + Sync + 'a> Sync
601     for MappedMutexGuard<'a, R, T>
602 {
603 }
604 unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + Send + 'a> Send for MappedMutexGuard<'a, R, T> where
605     R::GuardMarker: Send
606 {
607 }
608 
609 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> MappedMutexGuard<'a, R, T> {
610     /// Makes a new `MappedMutexGuard` for a component of the locked data.
611     ///
612     /// This operation cannot fail as the `MappedMutexGuard` passed
613     /// in already locked the mutex.
614     ///
615     /// This is an associated function that needs to be
616     /// used as `MappedMutexGuard::map(...)`. A method would interfere with methods of
617     /// the same name on the contents of the locked data.
618     #[inline]
map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U> where F: FnOnce(&mut T) -> &mut U,619     pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U>
620     where
621         F: FnOnce(&mut T) -> &mut U,
622     {
623         let raw = s.raw;
624         let data = f(unsafe { &mut *s.data });
625         mem::forget(s);
626         MappedMutexGuard {
627             raw,
628             data,
629             marker: PhantomData,
630         }
631     }
632 
633     /// Attempts to make a new `MappedMutexGuard` for a component of the
634     /// locked data. The original guard is returned if the closure returns `None`.
635     ///
636     /// This operation cannot fail as the `MappedMutexGuard` passed
637     /// in already locked the mutex.
638     ///
639     /// This is an associated function that needs to be
640     /// used as `MappedMutexGuard::try_map(...)`. A method would interfere with methods of
641     /// the same name on the contents of the locked data.
642     #[inline]
try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self> where F: FnOnce(&mut T) -> Option<&mut U>,643     pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self>
644     where
645         F: FnOnce(&mut T) -> Option<&mut U>,
646     {
647         let raw = s.raw;
648         let data = match f(unsafe { &mut *s.data }) {
649             Some(data) => data,
650             None => return Err(s),
651         };
652         mem::forget(s);
653         Ok(MappedMutexGuard {
654             raw,
655             data,
656             marker: PhantomData,
657         })
658     }
659 }
660 
661 impl<'a, R: RawMutexFair + 'a, T: ?Sized + 'a> MappedMutexGuard<'a, R, T> {
662     /// Unlocks the mutex using a fair unlock protocol.
663     ///
664     /// By default, mutexes are unfair and allow the current thread to re-lock
665     /// the mutex before another has the chance to acquire the lock, even if
666     /// that thread has been blocked on the mutex for a long time. This is the
667     /// default because it allows much higher throughput as it avoids forcing a
668     /// context switch on every mutex unlock. This can result in one thread
669     /// acquiring a mutex many more times than other threads.
670     ///
671     /// However in some cases it can be beneficial to ensure fairness by forcing
672     /// the lock to pass on to a waiting thread if there is one. This is done by
673     /// using this method instead of dropping the `MutexGuard` normally.
674     #[inline]
unlock_fair(s: Self)675     pub fn unlock_fair(s: Self) {
676         // Safety: A MutexGuard always holds the lock.
677         unsafe {
678             s.raw.unlock_fair();
679         }
680         mem::forget(s);
681     }
682 }
683 
684 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Deref for MappedMutexGuard<'a, R, T> {
685     type Target = T;
686     #[inline]
deref(&self) -> &T687     fn deref(&self) -> &T {
688         unsafe { &*self.data }
689     }
690 }
691 
692 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> DerefMut for MappedMutexGuard<'a, R, T> {
693     #[inline]
deref_mut(&mut self) -> &mut T694     fn deref_mut(&mut self) -> &mut T {
695         unsafe { &mut *self.data }
696     }
697 }
698 
699 impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Drop for MappedMutexGuard<'a, R, T> {
700     #[inline]
drop(&mut self)701     fn drop(&mut self) {
702         // Safety: A MappedMutexGuard always holds the lock.
703         unsafe {
704             self.raw.unlock();
705         }
706     }
707 }
708 
709 impl<'a, R: RawMutex + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for MappedMutexGuard<'a, R, T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result710     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
711         fmt::Debug::fmt(&**self, f)
712     }
713 }
714 
715 impl<'a, R: RawMutex + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display
716     for MappedMutexGuard<'a, R, T>
717 {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result718     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
719         (**self).fmt(f)
720     }
721 }
722 
723 #[cfg(feature = "owning_ref")]
724 unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> StableAddress for MappedMutexGuard<'a, R, T> {}
725