1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
14 use ops::{Deref, DerefMut};
16 use sys_common::mutex as sys;
17 use sys_common::poison::{self, TryLockError, TryLockResult, LockResult};
19 /// A mutual exclusion primitive useful for protecting shared data
21 /// This mutex will block threads waiting for the lock to become available. The
22 /// mutex can also be statically initialized or created via a [`new`]
23 /// constructor. Each mutex has a type parameter which represents the data that
24 /// it is protecting. The data can only be accessed through the RAII guards
25 /// returned from [`lock`] and [`try_lock`], which guarantees that the data is only
26 /// ever accessed when the mutex is locked.
30 /// The mutexes in this module implement a strategy called "poisoning" where a
31 /// mutex is considered poisoned whenever a thread panics while holding the
32 /// mutex. Once a mutex is poisoned, all other threads are unable to access the
33 /// data by default as it is likely tainted (some invariant is not being
36 /// For a mutex, this means that the [`lock`] and [`try_lock`] methods return a
37 /// [`Result`] which indicates whether a mutex has been poisoned or not. Most
38 /// usage of a mutex will simply [`unwrap()`] these results, propagating panics
39 /// among threads to ensure that a possibly invalid invariant is not witnessed.
41 /// A poisoned mutex, however, does not prevent all access to the underlying
42 /// data. The [`PoisonError`] type has an [`into_inner`] method which will return
43 /// the guard that would have otherwise been returned on a successful lock. This
44 /// allows access to the data, despite the lock being poisoned.
46 /// [`new`]: #method.new
47 /// [`lock`]: #method.lock
48 /// [`try_lock`]: #method.try_lock
49 /// [`Result`]: ../../std/result/enum.Result.html
50 /// [`unwrap()`]: ../../std/result/enum.Result.html#method.unwrap
51 /// [`PoisonError`]: ../../std/sync/struct.PoisonError.html
52 /// [`into_inner`]: ../../std/sync/struct.PoisonError.html#method.into_inner
57 /// use std::sync::{Arc, Mutex};
59 /// use std::sync::mpsc::channel;
61 /// const N: usize = 10;
63 /// // Spawn a few threads to increment a shared variable (non-atomically), and
64 /// // let the main thread know once all increments are done.
66 /// // Here we're using an Arc to share memory among threads, and the data inside
67 /// // the Arc is protected with a mutex.
68 /// let data = Arc::new(Mutex::new(0));
70 /// let (tx, rx) = channel();
72 /// let (data, tx) = (Arc::clone(&data), tx.clone());
73 /// thread::spawn(move || {
74 /// // The shared state can only be accessed once the lock is held.
75 /// // Our non-atomic increment is safe because we're the only thread
76 /// // which can access the shared state when the lock is held.
78 /// // We unwrap() the return value to assert that we are not expecting
79 /// // threads to ever fail while holding the lock.
80 /// let mut data = data.lock().unwrap();
83 /// tx.send(()).unwrap();
85 /// // the lock is unlocked here when `data` goes out of scope.
89 /// rx.recv().unwrap();
92 /// To recover from a poisoned mutex:
95 /// use std::sync::{Arc, Mutex};
98 /// let lock = Arc::new(Mutex::new(0_u32));
99 /// let lock2 = lock.clone();
101 /// let _ = thread::spawn(move || -> () {
102 /// // This thread will acquire the mutex first, unwrapping the result of
103 /// // `lock` because the lock has not been poisoned.
104 /// let _guard = lock2.lock().unwrap();
106 /// // This panic while holding the lock (`_guard` is in scope) will poison
111 /// // The lock is poisoned by this point, but the returned result can be
112 /// // pattern matched on to return the underlying guard on both branches.
113 /// let mut guard = match lock.lock() {
114 /// Ok(guard) => guard,
115 /// Err(poisoned) => poisoned.into_inner(),
120 #[stable(feature = "rust1", since = "1.0.0")]
121 pub struct Mutex<T: ?Sized> {
122 // Note that this mutex is in a *box*, not inlined into the struct itself.
123 // Once a native mutex has been used once, its address can never change (it
124 // can't be moved). This mutex type can be safely moved at any time, so to
125 // ensure that the native mutex is used correctly we box the inner mutex to
126 // give it a constant address.
127 inner: Box<sys::Mutex>,
128 poison: poison::Flag,
132 // these are the only places where `T: Send` matters; all other
133 // functionality works fine on a single thread.
134 #[stable(feature = "rust1", since = "1.0.0")]
135 unsafe impl<T: ?Sized + Send> Send for Mutex<T> { }
136 #[stable(feature = "rust1", since = "1.0.0")]
137 unsafe impl<T: ?Sized + Send> Sync for Mutex<T> { }
139 /// An RAII implementation of a "scoped lock" of a mutex. When this structure is
140 /// dropped (falls out of scope), the lock will be unlocked.
142 /// The data protected by the mutex can be accessed through this guard via its
143 /// [`Deref`] and [`DerefMut`] implementations.
145 /// This structure is created by the [`lock`] and [`try_lock`] methods on
148 /// [`Deref`]: ../../std/ops/trait.Deref.html
149 /// [`DerefMut`]: ../../std/ops/trait.DerefMut.html
150 /// [`lock`]: struct.Mutex.html#method.lock
151 /// [`try_lock`]: struct.Mutex.html#method.try_lock
152 /// [`Mutex`]: struct.Mutex.html
153 #[must_use = "if unused the Mutex will immediately unlock"]
154 #[stable(feature = "rust1", since = "1.0.0")]
155 pub struct MutexGuard<'a, T: ?Sized + 'a> {
156 // funny underscores due to how Deref/DerefMut currently work (they
157 // disregard field privacy).
158 __lock: &'a Mutex<T>,
159 __poison: poison::Guard,
162 #[stable(feature = "rust1", since = "1.0.0")]
163 impl<'a, T: ?Sized> !Send for MutexGuard<'a, T> { }
164 #[stable(feature = "mutexguard", since = "1.19.0")]
165 unsafe impl<'a, T: ?Sized + Sync> Sync for MutexGuard<'a, T> { }
168 /// Creates a new mutex in an unlocked state ready for use.
173 /// use std::sync::Mutex;
175 /// let mutex = Mutex::new(0);
177 #[stable(feature = "rust1", since = "1.0.0")]
178 pub fn new(t: T) -> Mutex<T> {
180 inner: box sys::Mutex::new(),
181 poison: poison::Flag::new(),
182 data: UnsafeCell::new(t),
191 impl<T: ?Sized> Mutex<T> {
192 /// Acquires a mutex, blocking the current thread until it is able to do so.
194 /// This function will block the local thread until it is available to acquire
195 /// the mutex. Upon returning, the thread is the only thread with the lock
196 /// held. An RAII guard is returned to allow scoped unlock of the lock. When
197 /// the guard goes out of scope, the mutex will be unlocked.
199 /// The exact behavior on locking a mutex in the thread which already holds
200 /// the lock is left unspecified. However, this function will not return on
201 /// the second call (it might panic or deadlock, for example).
205 /// If another user of this mutex panicked while holding the mutex, then
206 /// this call will return an error once the mutex is acquired.
210 /// This function might panic when called if the lock is already held by
211 /// the current thread.
216 /// use std::sync::{Arc, Mutex};
219 /// let mutex = Arc::new(Mutex::new(0));
220 /// let c_mutex = mutex.clone();
222 /// thread::spawn(move || {
223 /// *c_mutex.lock().unwrap() = 10;
224 /// }).join().expect("thread::spawn failed");
225 /// assert_eq!(*mutex.lock().unwrap(), 10);
227 #[stable(feature = "rust1", since = "1.0.0")]
228 pub fn lock(&self) -> LockResult<MutexGuard<T>> {
230 self.inner.raw_lock();
231 MutexGuard::new(self)
235 /// Attempts to acquire this lock.
237 /// If the lock could not be acquired at this time, then [`Err`] is returned.
238 /// Otherwise, an RAII guard is returned. The lock will be unlocked when the
239 /// guard is dropped.
241 /// This function does not block.
245 /// If another user of this mutex panicked while holding the mutex, then
246 /// this call will return failure if the mutex would otherwise be
249 /// [`Err`]: ../../std/result/enum.Result.html#variant.Err
254 /// use std::sync::{Arc, Mutex};
257 /// let mutex = Arc::new(Mutex::new(0));
258 /// let c_mutex = mutex.clone();
260 /// thread::spawn(move || {
261 /// let mut lock = c_mutex.try_lock();
262 /// if let Ok(ref mut mutex) = lock {
265 /// println!("try_lock failed");
267 /// }).join().expect("thread::spawn failed");
268 /// assert_eq!(*mutex.lock().unwrap(), 10);
270 #[stable(feature = "rust1", since = "1.0.0")]
271 pub fn try_lock(&self) -> TryLockResult<MutexGuard<T>> {
273 if self.inner.try_lock() {
274 Ok(MutexGuard::new(self)?)
276 Err(TryLockError::WouldBlock)
281 /// Determines whether the mutex is poisoned.
283 /// If another thread is active, the mutex can still become poisoned at any
284 /// time. You should not trust a `false` value for program correctness
285 /// without additional synchronization.
290 /// use std::sync::{Arc, Mutex};
293 /// let mutex = Arc::new(Mutex::new(0));
294 /// let c_mutex = mutex.clone();
296 /// let _ = thread::spawn(move || {
297 /// let _lock = c_mutex.lock().unwrap();
298 /// panic!(); // the mutex gets poisoned
300 /// assert_eq!(mutex.is_poisoned(), true);
303 #[stable(feature = "sync_poison", since = "1.2.0")]
304 pub fn is_poisoned(&self) -> bool {
308 /// Consumes this mutex, returning the underlying data.
312 /// If another user of this mutex panicked while holding the mutex, then
313 /// this call will return an error instead.
318 /// use std::sync::Mutex;
320 /// let mutex = Mutex::new(0);
321 /// assert_eq!(mutex.into_inner().unwrap(), 0);
323 #[stable(feature = "mutex_into_inner", since = "1.6.0")]
324 pub fn into_inner(self) -> LockResult<T> where T: Sized {
325 // We know statically that there are no outstanding references to
326 // `self` so there's no need to lock the inner mutex.
328 // To get the inner value, we'd like to call `data.into_inner()`,
329 // but because `Mutex` impl-s `Drop`, we can't move out of it, so
330 // we'll have to destructure it manually instead.
332 // Like `let Mutex { inner, poison, data } = self`.
333 let (inner, poison, data) = {
334 let Mutex { ref inner, ref poison, ref data } = self;
335 (ptr::read(inner), ptr::read(poison), ptr::read(data))
338 inner.destroy(); // Keep in sync with the `Drop` impl.
341 poison::map_result(poison.borrow(), |_| data.into_inner())
345 /// Returns a mutable reference to the underlying data.
347 /// Since this call borrows the `Mutex` mutably, no actual locking needs to
348 /// take place---the mutable borrow statically guarantees no locks exist.
352 /// If another user of this mutex panicked while holding the mutex, then
353 /// this call will return an error instead.
358 /// use std::sync::Mutex;
360 /// let mut mutex = Mutex::new(0);
361 /// *mutex.get_mut().unwrap() = 10;
362 /// assert_eq!(*mutex.lock().unwrap(), 10);
364 #[stable(feature = "mutex_get_mut", since = "1.6.0")]
365 pub fn get_mut(&mut self) -> LockResult<&mut T> {
366 // We know statically that there are no other references to `self`, so
367 // there's no need to lock the inner mutex.
368 let data = unsafe { &mut *self.data.get() };
369 poison::map_result(self.poison.borrow(), |_| data )
373 #[stable(feature = "rust1", since = "1.0.0")]
374 unsafe impl<#[may_dangle] T: ?Sized> Drop for Mutex<T> {
376 // This is actually safe b/c we know that there is no further usage of
377 // this mutex (it's up to the user to arrange for a mutex to get
378 // dropped, that's not our job)
380 // IMPORTANT: This code must be kept in sync with `Mutex::into_inner`.
381 unsafe { self.inner.destroy() }
385 #[stable(feature = "mutex_from", since = "1.24.0")]
386 impl<T> From<T> for Mutex<T> {
387 /// Creates a new mutex in an unlocked state ready for use.
388 /// This is equivalent to [`Mutex::new`].
389 fn from(t: T) -> Self {
394 #[stable(feature = "mutex_default", since = "1.10.0")]
395 impl<T: ?Sized + Default> Default for Mutex<T> {
396 /// Creates a `Mutex<T>`, with the `Default` value for T.
397 fn default() -> Mutex<T> {
398 Mutex::new(Default::default())
402 #[stable(feature = "rust1", since = "1.0.0")]
403 impl<T: ?Sized + fmt::Debug> fmt::Debug for Mutex<T> {
404 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
405 match self.try_lock() {
406 Ok(guard) => f.debug_struct("Mutex").field("data", &&*guard).finish(),
407 Err(TryLockError::Poisoned(err)) => {
408 f.debug_struct("Mutex").field("data", &&**err.get_ref()).finish()
410 Err(TryLockError::WouldBlock) => {
411 struct LockedPlaceholder;
412 impl fmt::Debug for LockedPlaceholder {
413 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str("<locked>") }
416 f.debug_struct("Mutex").field("data", &LockedPlaceholder).finish()
422 impl<'mutex, T: ?Sized> MutexGuard<'mutex, T> {
423 unsafe fn new(lock: &'mutex Mutex<T>) -> LockResult<MutexGuard<'mutex, T>> {
424 poison::map_result(lock.poison.borrow(), |guard| {
433 #[stable(feature = "rust1", since = "1.0.0")]
434 impl<'mutex, T: ?Sized> Deref for MutexGuard<'mutex, T> {
437 fn deref(&self) -> &T {
438 unsafe { &*self.__lock.data.get() }
442 #[stable(feature = "rust1", since = "1.0.0")]
443 impl<'mutex, T: ?Sized> DerefMut for MutexGuard<'mutex, T> {
444 fn deref_mut(&mut self) -> &mut T {
445 unsafe { &mut *self.__lock.data.get() }
449 #[stable(feature = "rust1", since = "1.0.0")]
450 impl<'a, T: ?Sized> Drop for MutexGuard<'a, T> {
454 self.__lock.poison.done(&self.__poison);
455 self.__lock.inner.raw_unlock();
460 #[stable(feature = "std_debug", since = "1.16.0")]
461 impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'a, T> {
462 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
463 f.debug_struct("MutexGuard")
464 .field("lock", &self.__lock)
469 #[stable(feature = "std_guard_impls", since = "1.20.0")]
470 impl<'a, T: ?Sized + fmt::Display> fmt::Display for MutexGuard<'a, T> {
471 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
476 pub fn guard_lock<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a sys::Mutex {
480 pub fn guard_poison<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a poison::Flag {
484 #[cfg(all(test, not(target_os = "emscripten")))]
486 use sync::mpsc::channel;
487 use sync::{Arc, Mutex, Condvar};
488 use sync::atomic::{AtomicUsize, Ordering};
491 struct Packet<T>(Arc<(Mutex<T>, Condvar)>);
493 #[derive(Eq, PartialEq, Debug)]
498 let m = Mutex::new(());
499 drop(m.lock().unwrap());
500 drop(m.lock().unwrap());
508 let m = Arc::new(Mutex::new(0));
510 fn inc(m: &Mutex<u32>) {
512 *m.lock().unwrap() += 1;
516 let (tx, rx) = channel();
518 let tx2 = tx.clone();
520 thread::spawn(move|| { inc(&m2); tx2.send(()).unwrap(); });
521 let tx2 = tx.clone();
523 thread::spawn(move|| { inc(&m2); tx2.send(()).unwrap(); });
530 assert_eq!(*m.lock().unwrap(), J * K * 2);
535 let m = Mutex::new(());
536 *m.try_lock().unwrap() = ();
540 fn test_into_inner() {
541 let m = Mutex::new(NonCopy(10));
542 assert_eq!(m.into_inner().unwrap(), NonCopy(10));
546 fn test_into_inner_drop() {
547 struct Foo(Arc<AtomicUsize>);
550 self.0.fetch_add(1, Ordering::SeqCst);
553 let num_drops = Arc::new(AtomicUsize::new(0));
554 let m = Mutex::new(Foo(num_drops.clone()));
555 assert_eq!(num_drops.load(Ordering::SeqCst), 0);
557 let _inner = m.into_inner().unwrap();
558 assert_eq!(num_drops.load(Ordering::SeqCst), 0);
560 assert_eq!(num_drops.load(Ordering::SeqCst), 1);
564 fn test_into_inner_poison() {
565 let m = Arc::new(Mutex::new(NonCopy(10)));
567 let _ = thread::spawn(move || {
568 let _lock = m2.lock().unwrap();
569 panic!("test panic in inner thread to poison mutex");
572 assert!(m.is_poisoned());
573 match Arc::try_unwrap(m).unwrap().into_inner() {
574 Err(e) => assert_eq!(e.into_inner(), NonCopy(10)),
575 Ok(x) => panic!("into_inner of poisoned Mutex is Ok: {:?}", x),
581 let mut m = Mutex::new(NonCopy(10));
582 *m.get_mut().unwrap() = NonCopy(20);
583 assert_eq!(m.into_inner().unwrap(), NonCopy(20));
587 fn test_get_mut_poison() {
588 let m = Arc::new(Mutex::new(NonCopy(10)));
590 let _ = thread::spawn(move || {
591 let _lock = m2.lock().unwrap();
592 panic!("test panic in inner thread to poison mutex");
595 assert!(m.is_poisoned());
596 match Arc::try_unwrap(m).unwrap().get_mut() {
597 Err(e) => assert_eq!(*e.into_inner(), NonCopy(10)),
598 Ok(x) => panic!("get_mut of poisoned Mutex is Ok: {:?}", x),
603 fn test_mutex_arc_condvar() {
604 let packet = Packet(Arc::new((Mutex::new(false), Condvar::new())));
605 let packet2 = Packet(packet.0.clone());
606 let (tx, rx) = channel();
607 let _t = thread::spawn(move|| {
608 // wait until parent gets in
610 let &(ref lock, ref cvar) = &*packet2.0;
611 let mut lock = lock.lock().unwrap();
616 let &(ref lock, ref cvar) = &*packet.0;
617 let mut lock = lock.lock().unwrap();
618 tx.send(()).unwrap();
621 lock = cvar.wait(lock).unwrap();
626 fn test_arc_condvar_poison() {
627 let packet = Packet(Arc::new((Mutex::new(1), Condvar::new())));
628 let packet2 = Packet(packet.0.clone());
629 let (tx, rx) = channel();
631 let _t = thread::spawn(move || -> () {
633 let &(ref lock, ref cvar) = &*packet2.0;
634 let _g = lock.lock().unwrap();
636 // Parent should fail when it wakes up.
640 let &(ref lock, ref cvar) = &*packet.0;
641 let mut lock = lock.lock().unwrap();
642 tx.send(()).unwrap();
644 match cvar.wait(lock) {
647 assert_eq!(*lock, 1);
655 fn test_mutex_arc_poison() {
656 let arc = Arc::new(Mutex::new(1));
657 assert!(!arc.is_poisoned());
658 let arc2 = arc.clone();
659 let _ = thread::spawn(move|| {
660 let lock = arc2.lock().unwrap();
661 assert_eq!(*lock, 2);
663 assert!(arc.lock().is_err());
664 assert!(arc.is_poisoned());
668 fn test_mutex_arc_nested() {
669 // Tests nested mutexes and access
670 // to underlying data.
671 let arc = Arc::new(Mutex::new(1));
672 let arc2 = Arc::new(Mutex::new(arc));
673 let (tx, rx) = channel();
674 let _t = thread::spawn(move|| {
675 let lock = arc2.lock().unwrap();
676 let lock2 = lock.lock().unwrap();
677 assert_eq!(*lock2, 1);
678 tx.send(()).unwrap();
684 fn test_mutex_arc_access_in_unwind() {
685 let arc = Arc::new(Mutex::new(1));
686 let arc2 = arc.clone();
687 let _ = thread::spawn(move|| -> () {
691 impl Drop for Unwinder {
693 *self.i.lock().unwrap() += 1;
696 let _u = Unwinder { i: arc2 };
699 let lock = arc.lock().unwrap();
700 assert_eq!(*lock, 2);
704 fn test_mutex_unsized() {
705 let mutex: &Mutex<[i32]> = &Mutex::new([1, 2, 3]);
707 let b = &mut *mutex.lock().unwrap();
711 let comp: &[i32] = &[4, 2, 5];
712 assert_eq!(&*mutex.lock().unwrap(), comp);