std/sync/poison/
mutex.rs

1use crate::cell::UnsafeCell;
2use crate::fmt;
3use crate::marker::PhantomData;
4use crate::mem::{self, ManuallyDrop};
5use crate::ops::{Deref, DerefMut};
6use crate::ptr::NonNull;
7use crate::sync::{LockResult, PoisonError, TryLockError, TryLockResult, poison};
8use crate::sys::sync as sys;
9
10/// A mutual exclusion primitive useful for protecting shared data
11///
12/// This mutex will block threads waiting for the lock to become available. The
13/// mutex can be created via a [`new`] constructor. Each mutex has a type parameter
14/// which represents the data that it is protecting. The data can only be accessed
15/// through the RAII guards returned from [`lock`] and [`try_lock`], which
16/// guarantees that the data is only ever accessed when the mutex is locked.
17///
18/// # Poisoning
19///
20/// The mutexes in this module implement a strategy called "poisoning" where a
21/// mutex is considered poisoned whenever a thread panics while holding the
22/// mutex. Once a mutex is poisoned, all other threads are unable to access the
23/// data by default as it is likely tainted (some invariant is not being
24/// upheld).
25///
26/// For a mutex, this means that the [`lock`] and [`try_lock`] methods return a
27/// [`Result`] which indicates whether a mutex has been poisoned or not. Most
28/// usage of a mutex will simply [`unwrap()`] these results, propagating panics
29/// among threads to ensure that a possibly invalid invariant is not witnessed.
30///
31/// A poisoned mutex, however, does not prevent all access to the underlying
32/// data. The [`PoisonError`] type has an [`into_inner`] method which will return
33/// the guard that would have otherwise been returned on a successful lock. This
34/// allows access to the data, despite the lock being poisoned.
35///
36/// [`new`]: Self::new
37/// [`lock`]: Self::lock
38/// [`try_lock`]: Self::try_lock
39/// [`unwrap()`]: Result::unwrap
40/// [`PoisonError`]: super::PoisonError
41/// [`into_inner`]: super::PoisonError::into_inner
42///
43/// # Examples
44///
45/// ```
46/// use std::sync::{Arc, Mutex};
47/// use std::thread;
48/// use std::sync::mpsc::channel;
49///
50/// const N: usize = 10;
51///
52/// // Spawn a few threads to increment a shared variable (non-atomically), and
53/// // let the main thread know once all increments are done.
54/// //
55/// // Here we're using an Arc to share memory among threads, and the data inside
56/// // the Arc is protected with a mutex.
57/// let data = Arc::new(Mutex::new(0));
58///
59/// let (tx, rx) = channel();
60/// for _ in 0..N {
61///     let (data, tx) = (Arc::clone(&data), tx.clone());
62///     thread::spawn(move || {
63///         // The shared state can only be accessed once the lock is held.
64///         // Our non-atomic increment is safe because we're the only thread
65///         // which can access the shared state when the lock is held.
66///         //
67///         // We unwrap() the return value to assert that we are not expecting
68///         // threads to ever fail while holding the lock.
69///         let mut data = data.lock().unwrap();
70///         *data += 1;
71///         if *data == N {
72///             tx.send(()).unwrap();
73///         }
74///         // the lock is unlocked here when `data` goes out of scope.
75///     });
76/// }
77///
78/// rx.recv().unwrap();
79/// ```
80///
81/// To recover from a poisoned mutex:
82///
83/// ```
84/// use std::sync::{Arc, Mutex};
85/// use std::thread;
86///
87/// let lock = Arc::new(Mutex::new(0_u32));
88/// let lock2 = Arc::clone(&lock);
89///
90/// let _ = thread::spawn(move || -> () {
91///     // This thread will acquire the mutex first, unwrapping the result of
92///     // `lock` because the lock has not been poisoned.
93///     let _guard = lock2.lock().unwrap();
94///
95///     // This panic while holding the lock (`_guard` is in scope) will poison
96///     // the mutex.
97///     panic!();
98/// }).join();
99///
100/// // The lock is poisoned by this point, but the returned result can be
101/// // pattern matched on to return the underlying guard on both branches.
102/// let mut guard = match lock.lock() {
103///     Ok(guard) => guard,
104///     Err(poisoned) => poisoned.into_inner(),
105/// };
106///
107/// *guard += 1;
108/// ```
109///
110/// To unlock a mutex guard sooner than the end of the enclosing scope,
111/// either create an inner scope or drop the guard manually.
112///
113/// ```
114/// use std::sync::{Arc, Mutex};
115/// use std::thread;
116///
117/// const N: usize = 3;
118///
119/// let data_mutex = Arc::new(Mutex::new(vec![1, 2, 3, 4]));
120/// let res_mutex = Arc::new(Mutex::new(0));
121///
122/// let mut threads = Vec::with_capacity(N);
123/// (0..N).for_each(|_| {
124///     let data_mutex_clone = Arc::clone(&data_mutex);
125///     let res_mutex_clone = Arc::clone(&res_mutex);
126///
127///     threads.push(thread::spawn(move || {
128///         // Here we use a block to limit the lifetime of the lock guard.
129///         let result = {
130///             let mut data = data_mutex_clone.lock().unwrap();
131///             // This is the result of some important and long-ish work.
132///             let result = data.iter().fold(0, |acc, x| acc + x * 2);
133///             data.push(result);
134///             result
135///             // The mutex guard gets dropped here, together with any other values
136///             // created in the critical section.
137///         };
138///         // The guard created here is a temporary dropped at the end of the statement, i.e.
139///         // the lock would not remain being held even if the thread did some additional work.
140///         *res_mutex_clone.lock().unwrap() += result;
141///     }));
142/// });
143///
144/// let mut data = data_mutex.lock().unwrap();
145/// // This is the result of some important and long-ish work.
146/// let result = data.iter().fold(0, |acc, x| acc + x * 2);
147/// data.push(result);
148/// // We drop the `data` explicitly because it's not necessary anymore and the
149/// // thread still has work to do. This allows other threads to start working on
150/// // the data immediately, without waiting for the rest of the unrelated work
151/// // to be done here.
152/// //
153/// // It's even more important here than in the threads because we `.join` the
154/// // threads after that. If we had not dropped the mutex guard, a thread could
155/// // be waiting forever for it, causing a deadlock.
156/// // As in the threads, a block could have been used instead of calling the
157/// // `drop` function.
158/// drop(data);
159/// // Here the mutex guard is not assigned to a variable and so, even if the
160/// // scope does not end after this line, the mutex is still released: there is
161/// // no deadlock.
162/// *res_mutex.lock().unwrap() += result;
163///
164/// threads.into_iter().for_each(|thread| {
165///     thread
166///         .join()
167///         .expect("The thread creating or execution failed !")
168/// });
169///
170/// assert_eq!(*res_mutex.lock().unwrap(), 800);
171/// ```
172///
173#[stable(feature = "rust1", since = "1.0.0")]
174#[cfg_attr(not(test), rustc_diagnostic_item = "Mutex")]
175pub struct Mutex<T: ?Sized> {
176    inner: sys::Mutex,
177    poison: poison::Flag,
178    data: UnsafeCell<T>,
179}
180
181/// `T` must be `Send` for a [`Mutex`] to be `Send` because it is possible to acquire
182/// the owned `T` from the `Mutex` via [`into_inner`].
183///
184/// [`into_inner`]: Mutex::into_inner
185#[stable(feature = "rust1", since = "1.0.0")]
186unsafe impl<T: ?Sized + Send> Send for Mutex<T> {}
187
188/// `T` must be `Send` for [`Mutex`] to be `Sync`.
189/// This ensures that the protected data can be accessed safely from multiple threads
190/// without causing data races or other unsafe behavior.
191///
192/// [`Mutex<T>`] provides mutable access to `T` to one thread at a time. However, it's essential
193/// for `T` to be `Send` because it's not safe for non-`Send` structures to be accessed in
194/// this manner. For instance, consider [`Rc`], a non-atomic reference counted smart pointer,
195/// which is not `Send`. With `Rc`, we can have multiple copies pointing to the same heap
196/// allocation with a non-atomic reference count. If we were to use `Mutex<Rc<_>>`, it would
197/// only protect one instance of `Rc` from shared access, leaving other copies vulnerable
198/// to potential data races.
199///
200/// Also note that it is not necessary for `T` to be `Sync` as `&T` is only made available
201/// to one thread at a time if `T` is not `Sync`.
202///
203/// [`Rc`]: crate::rc::Rc
204#[stable(feature = "rust1", since = "1.0.0")]
205unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
206
207/// An RAII implementation of a "scoped lock" of a mutex. When this structure is
208/// dropped (falls out of scope), the lock will be unlocked.
209///
210/// The data protected by the mutex can be accessed through this guard via its
211/// [`Deref`] and [`DerefMut`] implementations.
212///
213/// This structure is created by the [`lock`] and [`try_lock`] methods on
214/// [`Mutex`].
215///
216/// [`lock`]: Mutex::lock
217/// [`try_lock`]: Mutex::try_lock
218#[must_use = "if unused the Mutex will immediately unlock"]
219#[must_not_suspend = "holding a MutexGuard across suspend \
220                      points can cause deadlocks, delays, \
221                      and cause Futures to not implement `Send`"]
222#[stable(feature = "rust1", since = "1.0.0")]
223#[clippy::has_significant_drop]
224#[cfg_attr(not(test), rustc_diagnostic_item = "MutexGuard")]
225pub struct MutexGuard<'a, T: ?Sized + 'a> {
226    lock: &'a Mutex<T>,
227    poison: poison::Guard,
228}
229
230/// A [`MutexGuard`] is not `Send` to maximize platform portablity.
231///
232/// On platforms that use POSIX threads (commonly referred to as pthreads) there is a requirement to
233/// release mutex locks on the same thread they were acquired.
234/// For this reason, [`MutexGuard`] must not implement `Send` to prevent it being dropped from
235/// another thread.
236#[stable(feature = "rust1", since = "1.0.0")]
237impl<T: ?Sized> !Send for MutexGuard<'_, T> {}
238
239/// `T` must be `Sync` for a [`MutexGuard<T>`] to be `Sync`
240/// because it is possible to get a `&T` from `&MutexGuard` (via `Deref`).
241#[stable(feature = "mutexguard", since = "1.19.0")]
242unsafe impl<T: ?Sized + Sync> Sync for MutexGuard<'_, T> {}
243
244/// An RAII mutex guard returned by `MutexGuard::map`, which can point to a
245/// subfield of the protected data. When this structure is dropped (falls out
246/// of scope), the lock will be unlocked.
247///
248/// The main difference between `MappedMutexGuard` and [`MutexGuard`] is that the
249/// former cannot be used with [`Condvar`], since that
250/// could introduce soundness issues if the locked object is modified by another
251/// thread while the `Mutex` is unlocked.
252///
253/// The data protected by the mutex can be accessed through this guard via its
254/// [`Deref`] and [`DerefMut`] implementations.
255///
256/// This structure is created by the [`map`] and [`try_map`] methods on
257/// [`MutexGuard`].
258///
259/// [`map`]: MutexGuard::map
260/// [`try_map`]: MutexGuard::try_map
261/// [`Condvar`]: crate::sync::Condvar
262#[must_use = "if unused the Mutex will immediately unlock"]
263#[must_not_suspend = "holding a MappedMutexGuard across suspend \
264                      points can cause deadlocks, delays, \
265                      and cause Futures to not implement `Send`"]
266#[unstable(feature = "mapped_lock_guards", issue = "117108")]
267#[clippy::has_significant_drop]
268pub struct MappedMutexGuard<'a, T: ?Sized + 'a> {
269    // NB: we use a pointer instead of `&'a mut T` to avoid `noalias` violations, because a
270    // `MappedMutexGuard` argument doesn't hold uniqueness for its whole scope, only until it drops.
271    // `NonNull` is covariant over `T`, so we add a `PhantomData<&'a mut T>` field
272    // below for the correct variance over `T` (invariance).
273    data: NonNull<T>,
274    inner: &'a sys::Mutex,
275    poison_flag: &'a poison::Flag,
276    poison: poison::Guard,
277    _variance: PhantomData<&'a mut T>,
278}
279
280#[unstable(feature = "mapped_lock_guards", issue = "117108")]
281impl<T: ?Sized> !Send for MappedMutexGuard<'_, T> {}
282#[unstable(feature = "mapped_lock_guards", issue = "117108")]
283unsafe impl<T: ?Sized + Sync> Sync for MappedMutexGuard<'_, T> {}
284
285impl<T> Mutex<T> {
286    /// Creates a new mutex in an unlocked state ready for use.
287    ///
288    /// # Examples
289    ///
290    /// ```
291    /// use std::sync::Mutex;
292    ///
293    /// let mutex = Mutex::new(0);
294    /// ```
295    #[stable(feature = "rust1", since = "1.0.0")]
296    #[rustc_const_stable(feature = "const_locks", since = "1.63.0")]
297    #[inline]
298    pub const fn new(t: T) -> Mutex<T> {
299        Mutex { inner: sys::Mutex::new(), poison: poison::Flag::new(), data: UnsafeCell::new(t) }
300    }
301
302    /// Returns the contained value by cloning it.
303    ///
304    /// # Errors
305    ///
306    /// If another user of this mutex panicked while holding the mutex, then
307    /// this call will return an error instead.
308    ///
309    /// # Examples
310    ///
311    /// ```
312    /// #![feature(lock_value_accessors)]
313    ///
314    /// use std::sync::Mutex;
315    ///
316    /// let mut mutex = Mutex::new(7);
317    ///
318    /// assert_eq!(mutex.get_cloned().unwrap(), 7);
319    /// ```
320    #[unstable(feature = "lock_value_accessors", issue = "133407")]
321    pub fn get_cloned(&self) -> Result<T, PoisonError<()>>
322    where
323        T: Clone,
324    {
325        match self.lock() {
326            Ok(guard) => Ok((*guard).clone()),
327            Err(_) => Err(PoisonError::new(())),
328        }
329    }
330
331    /// Sets the contained value.
332    ///
333    /// # Errors
334    ///
335    /// If another user of this mutex panicked while holding the mutex, then
336    /// this call will return an error containing the provided `value` instead.
337    ///
338    /// # Examples
339    ///
340    /// ```
341    /// #![feature(lock_value_accessors)]
342    ///
343    /// use std::sync::Mutex;
344    ///
345    /// let mut mutex = Mutex::new(7);
346    ///
347    /// assert_eq!(mutex.get_cloned().unwrap(), 7);
348    /// mutex.set(11).unwrap();
349    /// assert_eq!(mutex.get_cloned().unwrap(), 11);
350    /// ```
351    #[unstable(feature = "lock_value_accessors", issue = "133407")]
352    pub fn set(&self, value: T) -> Result<(), PoisonError<T>> {
353        if mem::needs_drop::<T>() {
354            // If the contained value has non-trivial destructor, we
355            // call that destructor after the lock being released.
356            self.replace(value).map(drop)
357        } else {
358            match self.lock() {
359                Ok(mut guard) => {
360                    *guard = value;
361
362                    Ok(())
363                }
364                Err(_) => Err(PoisonError::new(value)),
365            }
366        }
367    }
368
369    /// Replaces the contained value with `value`, and returns the old contained value.
370    ///
371    /// # Errors
372    ///
373    /// If another user of this mutex panicked while holding the mutex, then
374    /// this call will return an error containing the provided `value` instead.
375    ///
376    /// # Examples
377    ///
378    /// ```
379    /// #![feature(lock_value_accessors)]
380    ///
381    /// use std::sync::Mutex;
382    ///
383    /// let mut mutex = Mutex::new(7);
384    ///
385    /// assert_eq!(mutex.replace(11).unwrap(), 7);
386    /// assert_eq!(mutex.get_cloned().unwrap(), 11);
387    /// ```
388    #[unstable(feature = "lock_value_accessors", issue = "133407")]
389    pub fn replace(&self, value: T) -> LockResult<T> {
390        match self.lock() {
391            Ok(mut guard) => Ok(mem::replace(&mut *guard, value)),
392            Err(_) => Err(PoisonError::new(value)),
393        }
394    }
395}
396
397impl<T: ?Sized> Mutex<T> {
398    /// Acquires a mutex, blocking the current thread until it is able to do so.
399    ///
400    /// This function will block the local thread until it is available to acquire
401    /// the mutex. Upon returning, the thread is the only thread with the lock
402    /// held. An RAII guard is returned to allow scoped unlock of the lock. When
403    /// the guard goes out of scope, the mutex will be unlocked.
404    ///
405    /// The exact behavior on locking a mutex in the thread which already holds
406    /// the lock is left unspecified. However, this function will not return on
407    /// the second call (it might panic or deadlock, for example).
408    ///
409    /// # Errors
410    ///
411    /// If another user of this mutex panicked while holding the mutex, then
412    /// this call will return an error once the mutex is acquired. The acquired
413    /// mutex guard will be contained in the returned error.
414    ///
415    /// # Panics
416    ///
417    /// This function might panic when called if the lock is already held by
418    /// the current thread.
419    ///
420    /// # Examples
421    ///
422    /// ```
423    /// use std::sync::{Arc, Mutex};
424    /// use std::thread;
425    ///
426    /// let mutex = Arc::new(Mutex::new(0));
427    /// let c_mutex = Arc::clone(&mutex);
428    ///
429    /// thread::spawn(move || {
430    ///     *c_mutex.lock().unwrap() = 10;
431    /// }).join().expect("thread::spawn failed");
432    /// assert_eq!(*mutex.lock().unwrap(), 10);
433    /// ```
434    #[stable(feature = "rust1", since = "1.0.0")]
435    pub fn lock(&self) -> LockResult<MutexGuard<'_, T>> {
436        unsafe {
437            self.inner.lock();
438            MutexGuard::new(self)
439        }
440    }
441
442    /// Attempts to acquire this lock.
443    ///
444    /// If the lock could not be acquired at this time, then [`Err`] is returned.
445    /// Otherwise, an RAII guard is returned. The lock will be unlocked when the
446    /// guard is dropped.
447    ///
448    /// This function does not block.
449    ///
450    /// # Errors
451    ///
452    /// If another user of this mutex panicked while holding the mutex, then
453    /// this call will return the [`Poisoned`] error if the mutex would
454    /// otherwise be acquired. An acquired lock guard will be contained
455    /// in the returned error.
456    ///
457    /// If the mutex could not be acquired because it is already locked, then
458    /// this call will return the [`WouldBlock`] error.
459    ///
460    /// [`Poisoned`]: TryLockError::Poisoned
461    /// [`WouldBlock`]: TryLockError::WouldBlock
462    ///
463    /// # Examples
464    ///
465    /// ```
466    /// use std::sync::{Arc, Mutex};
467    /// use std::thread;
468    ///
469    /// let mutex = Arc::new(Mutex::new(0));
470    /// let c_mutex = Arc::clone(&mutex);
471    ///
472    /// thread::spawn(move || {
473    ///     let mut lock = c_mutex.try_lock();
474    ///     if let Ok(ref mut mutex) = lock {
475    ///         **mutex = 10;
476    ///     } else {
477    ///         println!("try_lock failed");
478    ///     }
479    /// }).join().expect("thread::spawn failed");
480    /// assert_eq!(*mutex.lock().unwrap(), 10);
481    /// ```
482    #[stable(feature = "rust1", since = "1.0.0")]
483    pub fn try_lock(&self) -> TryLockResult<MutexGuard<'_, T>> {
484        unsafe {
485            if self.inner.try_lock() {
486                Ok(MutexGuard::new(self)?)
487            } else {
488                Err(TryLockError::WouldBlock)
489            }
490        }
491    }
492
493    /// Determines whether the mutex is poisoned.
494    ///
495    /// If another thread is active, the mutex can still become poisoned at any
496    /// time. You should not trust a `false` value for program correctness
497    /// without additional synchronization.
498    ///
499    /// # Examples
500    ///
501    /// ```
502    /// use std::sync::{Arc, Mutex};
503    /// use std::thread;
504    ///
505    /// let mutex = Arc::new(Mutex::new(0));
506    /// let c_mutex = Arc::clone(&mutex);
507    ///
508    /// let _ = thread::spawn(move || {
509    ///     let _lock = c_mutex.lock().unwrap();
510    ///     panic!(); // the mutex gets poisoned
511    /// }).join();
512    /// assert_eq!(mutex.is_poisoned(), true);
513    /// ```
514    #[inline]
515    #[stable(feature = "sync_poison", since = "1.2.0")]
516    pub fn is_poisoned(&self) -> bool {
517        self.poison.get()
518    }
519
520    /// Clear the poisoned state from a mutex.
521    ///
522    /// If the mutex is poisoned, it will remain poisoned until this function is called. This
523    /// allows recovering from a poisoned state and marking that it has recovered. For example, if
524    /// the value is overwritten by a known-good value, then the mutex can be marked as
525    /// un-poisoned. Or possibly, the value could be inspected to determine if it is in a
526    /// consistent state, and if so the poison is removed.
527    ///
528    /// # Examples
529    ///
530    /// ```
531    /// use std::sync::{Arc, Mutex};
532    /// use std::thread;
533    ///
534    /// let mutex = Arc::new(Mutex::new(0));
535    /// let c_mutex = Arc::clone(&mutex);
536    ///
537    /// let _ = thread::spawn(move || {
538    ///     let _lock = c_mutex.lock().unwrap();
539    ///     panic!(); // the mutex gets poisoned
540    /// }).join();
541    ///
542    /// assert_eq!(mutex.is_poisoned(), true);
543    /// let x = mutex.lock().unwrap_or_else(|mut e| {
544    ///     **e.get_mut() = 1;
545    ///     mutex.clear_poison();
546    ///     e.into_inner()
547    /// });
548    /// assert_eq!(mutex.is_poisoned(), false);
549    /// assert_eq!(*x, 1);
550    /// ```
551    #[inline]
552    #[stable(feature = "mutex_unpoison", since = "1.77.0")]
553    pub fn clear_poison(&self) {
554        self.poison.clear();
555    }
556
557    /// Consumes this mutex, returning the underlying data.
558    ///
559    /// # Errors
560    ///
561    /// If another user of this mutex panicked while holding the mutex, then
562    /// this call will return an error containing the underlying data
563    /// instead.
564    ///
565    /// # Examples
566    ///
567    /// ```
568    /// use std::sync::Mutex;
569    ///
570    /// let mutex = Mutex::new(0);
571    /// assert_eq!(mutex.into_inner().unwrap(), 0);
572    /// ```
573    #[stable(feature = "mutex_into_inner", since = "1.6.0")]
574    pub fn into_inner(self) -> LockResult<T>
575    where
576        T: Sized,
577    {
578        let data = self.data.into_inner();
579        poison::map_result(self.poison.borrow(), |()| data)
580    }
581
582    /// Returns a mutable reference to the underlying data.
583    ///
584    /// Since this call borrows the `Mutex` mutably, no actual locking needs to
585    /// take place -- the mutable borrow statically guarantees no locks exist.
586    ///
587    /// # Errors
588    ///
589    /// If another user of this mutex panicked while holding the mutex, then
590    /// this call will return an error containing a mutable reference to the
591    /// underlying data instead.
592    ///
593    /// # Examples
594    ///
595    /// ```
596    /// use std::sync::Mutex;
597    ///
598    /// let mut mutex = Mutex::new(0);
599    /// *mutex.get_mut().unwrap() = 10;
600    /// assert_eq!(*mutex.lock().unwrap(), 10);
601    /// ```
602    #[stable(feature = "mutex_get_mut", since = "1.6.0")]
603    pub fn get_mut(&mut self) -> LockResult<&mut T> {
604        let data = self.data.get_mut();
605        poison::map_result(self.poison.borrow(), |()| data)
606    }
607}
608
609#[stable(feature = "mutex_from", since = "1.24.0")]
610impl<T> From<T> for Mutex<T> {
611    /// Creates a new mutex in an unlocked state ready for use.
612    /// This is equivalent to [`Mutex::new`].
613    fn from(t: T) -> Self {
614        Mutex::new(t)
615    }
616}
617
618#[stable(feature = "mutex_default", since = "1.10.0")]
619impl<T: ?Sized + Default> Default for Mutex<T> {
620    /// Creates a `Mutex<T>`, with the `Default` value for T.
621    fn default() -> Mutex<T> {
622        Mutex::new(Default::default())
623    }
624}
625
626#[stable(feature = "rust1", since = "1.0.0")]
627impl<T: ?Sized + fmt::Debug> fmt::Debug for Mutex<T> {
628    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
629        let mut d = f.debug_struct("Mutex");
630        match self.try_lock() {
631            Ok(guard) => {
632                d.field("data", &&*guard);
633            }
634            Err(TryLockError::Poisoned(err)) => {
635                d.field("data", &&**err.get_ref());
636            }
637            Err(TryLockError::WouldBlock) => {
638                d.field("data", &format_args!("<locked>"));
639            }
640        }
641        d.field("poisoned", &self.poison.get());
642        d.finish_non_exhaustive()
643    }
644}
645
646impl<'mutex, T: ?Sized> MutexGuard<'mutex, T> {
647    unsafe fn new(lock: &'mutex Mutex<T>) -> LockResult<MutexGuard<'mutex, T>> {
648        poison::map_result(lock.poison.guard(), |guard| MutexGuard { lock, poison: guard })
649    }
650}
651
652#[stable(feature = "rust1", since = "1.0.0")]
653impl<T: ?Sized> Deref for MutexGuard<'_, T> {
654    type Target = T;
655
656    fn deref(&self) -> &T {
657        unsafe { &*self.lock.data.get() }
658    }
659}
660
661#[stable(feature = "rust1", since = "1.0.0")]
662impl<T: ?Sized> DerefMut for MutexGuard<'_, T> {
663    fn deref_mut(&mut self) -> &mut T {
664        unsafe { &mut *self.lock.data.get() }
665    }
666}
667
668#[stable(feature = "rust1", since = "1.0.0")]
669impl<T: ?Sized> Drop for MutexGuard<'_, T> {
670    #[inline]
671    fn drop(&mut self) {
672        unsafe {
673            self.lock.poison.done(&self.poison);
674            self.lock.inner.unlock();
675        }
676    }
677}
678
679#[stable(feature = "std_debug", since = "1.16.0")]
680impl<T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'_, T> {
681    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
682        fmt::Debug::fmt(&**self, f)
683    }
684}
685
686#[stable(feature = "std_guard_impls", since = "1.20.0")]
687impl<T: ?Sized + fmt::Display> fmt::Display for MutexGuard<'_, T> {
688    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
689        (**self).fmt(f)
690    }
691}
692
693pub fn guard_lock<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a sys::Mutex {
694    &guard.lock.inner
695}
696
697pub fn guard_poison<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a poison::Flag {
698    &guard.lock.poison
699}
700
701impl<'a, T: ?Sized> MutexGuard<'a, T> {
702    /// Makes a [`MappedMutexGuard`] for a component of the borrowed data, e.g.
703    /// an enum variant.
704    ///
705    /// The `Mutex` is already locked, so this cannot fail.
706    ///
707    /// This is an associated function that needs to be used as
708    /// `MutexGuard::map(...)`. A method would interfere with methods of the
709    /// same name on the contents of the `MutexGuard` used through `Deref`.
710    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
711    pub fn map<U, F>(orig: Self, f: F) -> MappedMutexGuard<'a, U>
712    where
713        F: FnOnce(&mut T) -> &mut U,
714        U: ?Sized,
715    {
716        // SAFETY: the conditions of `MutexGuard::new` were satisfied when the original guard
717        // was created, and have been upheld throughout `map` and/or `try_map`.
718        // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
719        // passed to it. If the closure panics, the guard will be dropped.
720        let data = NonNull::from(f(unsafe { &mut *orig.lock.data.get() }));
721        let orig = ManuallyDrop::new(orig);
722        MappedMutexGuard {
723            data,
724            inner: &orig.lock.inner,
725            poison_flag: &orig.lock.poison,
726            poison: orig.poison.clone(),
727            _variance: PhantomData,
728        }
729    }
730
731    /// Makes a [`MappedMutexGuard`] for a component of the borrowed data. The
732    /// original guard is returned as an `Err(...)` if the closure returns
733    /// `None`.
734    ///
735    /// The `Mutex` is already locked, so this cannot fail.
736    ///
737    /// This is an associated function that needs to be used as
738    /// `MutexGuard::try_map(...)`. A method would interfere with methods of the
739    /// same name on the contents of the `MutexGuard` used through `Deref`.
740    #[doc(alias = "filter_map")]
741    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
742    pub fn try_map<U, F>(orig: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
743    where
744        F: FnOnce(&mut T) -> Option<&mut U>,
745        U: ?Sized,
746    {
747        // SAFETY: the conditions of `MutexGuard::new` were satisfied when the original guard
748        // was created, and have been upheld throughout `map` and/or `try_map`.
749        // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
750        // passed to it. If the closure panics, the guard will be dropped.
751        match f(unsafe { &mut *orig.lock.data.get() }) {
752            Some(data) => {
753                let data = NonNull::from(data);
754                let orig = ManuallyDrop::new(orig);
755                Ok(MappedMutexGuard {
756                    data,
757                    inner: &orig.lock.inner,
758                    poison_flag: &orig.lock.poison,
759                    poison: orig.poison.clone(),
760                    _variance: PhantomData,
761                })
762            }
763            None => Err(orig),
764        }
765    }
766}
767
768#[unstable(feature = "mapped_lock_guards", issue = "117108")]
769impl<T: ?Sized> Deref for MappedMutexGuard<'_, T> {
770    type Target = T;
771
772    fn deref(&self) -> &T {
773        unsafe { self.data.as_ref() }
774    }
775}
776
777#[unstable(feature = "mapped_lock_guards", issue = "117108")]
778impl<T: ?Sized> DerefMut for MappedMutexGuard<'_, T> {
779    fn deref_mut(&mut self) -> &mut T {
780        unsafe { self.data.as_mut() }
781    }
782}
783
784#[unstable(feature = "mapped_lock_guards", issue = "117108")]
785impl<T: ?Sized> Drop for MappedMutexGuard<'_, T> {
786    #[inline]
787    fn drop(&mut self) {
788        unsafe {
789            self.poison_flag.done(&self.poison);
790            self.inner.unlock();
791        }
792    }
793}
794
795#[unstable(feature = "mapped_lock_guards", issue = "117108")]
796impl<T: ?Sized + fmt::Debug> fmt::Debug for MappedMutexGuard<'_, T> {
797    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
798        fmt::Debug::fmt(&**self, f)
799    }
800}
801
802#[unstable(feature = "mapped_lock_guards", issue = "117108")]
803impl<T: ?Sized + fmt::Display> fmt::Display for MappedMutexGuard<'_, T> {
804    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
805        (**self).fmt(f)
806    }
807}
808
809impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
810    /// Makes a [`MappedMutexGuard`] for a component of the borrowed data, e.g.
811    /// an enum variant.
812    ///
813    /// The `Mutex` is already locked, so this cannot fail.
814    ///
815    /// This is an associated function that needs to be used as
816    /// `MappedMutexGuard::map(...)`. A method would interfere with methods of the
817    /// same name on the contents of the `MutexGuard` used through `Deref`.
818    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
819    pub fn map<U, F>(mut orig: Self, f: F) -> MappedMutexGuard<'a, U>
820    where
821        F: FnOnce(&mut T) -> &mut U,
822        U: ?Sized,
823    {
824        // SAFETY: the conditions of `MutexGuard::new` were satisfied when the original guard
825        // was created, and have been upheld throughout `map` and/or `try_map`.
826        // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
827        // passed to it. If the closure panics, the guard will be dropped.
828        let data = NonNull::from(f(unsafe { orig.data.as_mut() }));
829        let orig = ManuallyDrop::new(orig);
830        MappedMutexGuard {
831            data,
832            inner: orig.inner,
833            poison_flag: orig.poison_flag,
834            poison: orig.poison.clone(),
835            _variance: PhantomData,
836        }
837    }
838
839    /// Makes a [`MappedMutexGuard`] for a component of the borrowed data. The
840    /// original guard is returned as an `Err(...)` if the closure returns
841    /// `None`.
842    ///
843    /// The `Mutex` is already locked, so this cannot fail.
844    ///
845    /// This is an associated function that needs to be used as
846    /// `MappedMutexGuard::try_map(...)`. A method would interfere with methods of the
847    /// same name on the contents of the `MutexGuard` used through `Deref`.
848    #[doc(alias = "filter_map")]
849    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
850    pub fn try_map<U, F>(mut orig: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
851    where
852        F: FnOnce(&mut T) -> Option<&mut U>,
853        U: ?Sized,
854    {
855        // SAFETY: the conditions of `MutexGuard::new` were satisfied when the original guard
856        // was created, and have been upheld throughout `map` and/or `try_map`.
857        // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
858        // passed to it. If the closure panics, the guard will be dropped.
859        match f(unsafe { orig.data.as_mut() }) {
860            Some(data) => {
861                let data = NonNull::from(data);
862                let orig = ManuallyDrop::new(orig);
863                Ok(MappedMutexGuard {
864                    data,
865                    inner: orig.inner,
866                    poison_flag: orig.poison_flag,
867                    poison: orig.poison.clone(),
868                    _variance: PhantomData,
869                })
870            }
871            None => Err(orig),
872        }
873    }
874}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy