1#[cfg(all(test, not(target_os = "emscripten")))]
2mod tests;
3
4use crate::cell::UnsafeCell;
5use crate::fmt;
6use crate::ops::{Deref, DerefMut};
7use crate::sync::{poison, LockResult, TryLockError, TryLockResult};
8use crate::sys::locks 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// these are the only places where `T: Send` matters; all other
182// functionality works fine on a single thread.
183#[stable(feature = "rust1", since = "1.0.0")]
184unsafe impl<T: ?Sized + Send> Send for Mutex<T> {}
185#[stable(feature = "rust1", since = "1.0.0")]
186unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
187
188/// An RAII implementation of a "scoped lock" of a mutex. When this structure is
189/// dropped (falls out of scope), the lock will be unlocked.
190///
191/// The data protected by the mutex can be accessed through this guard via its
192/// [`Deref`] and [`DerefMut`] implementations.
193///
194/// This structure is created by the [`lock`] and [`try_lock`] methods on
195/// [`Mutex`].
196///
197/// [`lock`]: Mutex::lock
198/// [`try_lock`]: Mutex::try_lock
199#[must_use = "if unused the Mutex will immediately unlock"]
200#[must_not_suspend = "holding a MutexGuard across suspend \
201 points can cause deadlocks, delays, \
202 and cause Futures to not implement `Send`"]
203#[stable(feature = "rust1", since = "1.0.0")]
204#[clippy::has_significant_drop]
205#[cfg_attr(not(test), rustc_diagnostic_item = "MutexGuard")]
206pub struct MutexGuard<'a, T: ?Sized + 'a> {
207 lock: &'a Mutex<T>,
208 poison: poison::Guard,
209}
210
211#[stable(feature = "rust1", since = "1.0.0")]
212impl<T: ?Sized> !Send for MutexGuard<'_, T> {}
213#[stable(feature = "mutexguard", since = "1.19.0")]
214unsafe impl<T: ?Sized + Sync> Sync for MutexGuard<'_, T> {}
215
216impl<T> Mutex<T> {
217 /// Creates a new mutex in an unlocked state ready for use.
218 ///
219 /// # Examples
220 ///
221 /// ```
222 /// use std::sync::Mutex;
223 ///
224 /// let mutex = Mutex::new(0);
225 /// ```
226 #[stable(feature = "rust1", since = "1.0.0")]
227 #[rustc_const_stable(feature = "const_locks", since = "1.63.0")]
228 #[inline]
229 pub const fn new(t: T) -> Mutex<T> {
230 Mutex { inner: sys::Mutex::new(), poison: poison::Flag::new(), data: UnsafeCell::new(t) }
231 }
232}
233
234impl<T: ?Sized> Mutex<T> {
235 /// Acquires a mutex, blocking the current thread until it is able to do so.
236 ///
237 /// This function will block the local thread until it is available to acquire
238 /// the mutex. Upon returning, the thread is the only thread with the lock
239 /// held. An RAII guard is returned to allow scoped unlock of the lock. When
240 /// the guard goes out of scope, the mutex will be unlocked.
241 ///
242 /// The exact behavior on locking a mutex in the thread which already holds
243 /// the lock is left unspecified. However, this function will not return on
244 /// the second call (it might panic or deadlock, for example).
245 ///
246 /// # Errors
247 ///
248 /// If another user of this mutex panicked while holding the mutex, then
249 /// this call will return an error once the mutex is acquired.
250 ///
251 /// # Panics
252 ///
253 /// This function might panic when called if the lock is already held by
254 /// the current thread.
255 ///
256 /// # Examples
257 ///
258 /// ```
259 /// use std::sync::{Arc, Mutex};
260 /// use std::thread;
261 ///
262 /// let mutex = Arc::new(Mutex::new(0));
263 /// let c_mutex = Arc::clone(&mutex);
264 ///
265 /// thread::spawn(move || {
266 /// *c_mutex.lock().unwrap() = 10;
267 /// }).join().expect("thread::spawn failed");
268 /// assert_eq!(*mutex.lock().unwrap(), 10);
269 /// ```
270 #[stable(feature = "rust1", since = "1.0.0")]
271 pub fn lock(&self) -> LockResult<MutexGuard<'_, T>> {
272 unsafe {
273 self.inner.lock();
274 MutexGuard::new(self)
275 }
276 }
277
278 /// Attempts to acquire this lock.
279 ///
280 /// If the lock could not be acquired at this time, then [`Err`] is returned.
281 /// Otherwise, an RAII guard is returned. The lock will be unlocked when the
282 /// guard is dropped.
283 ///
284 /// This function does not block.
285 ///
286 /// # Errors
287 ///
288 /// If another user of this mutex panicked while holding the mutex, then
289 /// this call will return the [`Poisoned`] error if the mutex would
290 /// otherwise be acquired.
291 ///
292 /// If the mutex could not be acquired because it is already locked, then
293 /// this call will return the [`WouldBlock`] error.
294 ///
295 /// [`Poisoned`]: TryLockError::Poisoned
296 /// [`WouldBlock`]: TryLockError::WouldBlock
297 ///
298 /// # Examples
299 ///
300 /// ```
301 /// use std::sync::{Arc, Mutex};
302 /// use std::thread;
303 ///
304 /// let mutex = Arc::new(Mutex::new(0));
305 /// let c_mutex = Arc::clone(&mutex);
306 ///
307 /// thread::spawn(move || {
308 /// let mut lock = c_mutex.try_lock();
309 /// if let Ok(ref mut mutex) = lock {
310 /// **mutex = 10;
311 /// } else {
312 /// println!("try_lock failed");
313 /// }
314 /// }).join().expect("thread::spawn failed");
315 /// assert_eq!(*mutex.lock().unwrap(), 10);
316 /// ```
317 #[stable(feature = "rust1", since = "1.0.0")]
318 pub fn try_lock(&self) -> TryLockResult<MutexGuard<'_, T>> {
319 unsafe {
320 if self.inner.try_lock() {
321 Ok(MutexGuard::new(self)?)
322 } else {
323 Err(TryLockError::WouldBlock)
324 }
325 }
326 }
327
328 /// Immediately drops the guard, and consequently unlocks the mutex.
329 ///
330 /// This function is equivalent to calling [`drop`] on the guard but is more self-documenting.
331 /// Alternately, the guard will be automatically dropped when it goes out of scope.
332 ///
333 /// ```
334 /// #![feature(mutex_unlock)]
335 ///
336 /// use std::sync::Mutex;
337 /// let mutex = Mutex::new(0);
338 ///
339 /// let mut guard = mutex.lock().unwrap();
340 /// *guard += 20;
341 /// Mutex::unlock(guard);
342 /// ```
343 #[unstable(feature = "mutex_unlock", issue = "81872")]
344 pub fn unlock(guard: MutexGuard<'_, T>) {
345 drop(guard);
346 }
347
348 /// Determines whether the mutex is poisoned.
349 ///
350 /// If another thread is active, the mutex can still become poisoned at any
351 /// time. You should not trust a `false` value for program correctness
352 /// without additional synchronization.
353 ///
354 /// # Examples
355 ///
356 /// ```
357 /// use std::sync::{Arc, Mutex};
358 /// use std::thread;
359 ///
360 /// let mutex = Arc::new(Mutex::new(0));
361 /// let c_mutex = Arc::clone(&mutex);
362 ///
363 /// let _ = thread::spawn(move || {
364 /// let _lock = c_mutex.lock().unwrap();
365 /// panic!(); // the mutex gets poisoned
366 /// }).join();
367 /// assert_eq!(mutex.is_poisoned(), true);
368 /// ```
369 #[inline]
370 #[stable(feature = "sync_poison", since = "1.2.0")]
371 pub fn is_poisoned(&self) -> bool {
372 self.poison.get()
373 }
374
375 /// Clear the poisoned state from a mutex
376 ///
377 /// If the mutex is poisoned, it will remain poisoned until this function is called. This
378 /// allows recovering from a poisoned state and marking that it has recovered. For example, if
379 /// the value is overwritten by a known-good value, then the mutex can be marked as
380 /// un-poisoned. Or possibly, the value could be inspected to determine if it is in a
381 /// consistent state, and if so the poison is removed.
382 ///
383 /// # Examples
384 ///
385 /// ```
386 /// use std::sync::{Arc, Mutex};
387 /// use std::thread;
388 ///
389 /// let mutex = Arc::new(Mutex::new(0));
390 /// let c_mutex = Arc::clone(&mutex);
391 ///
392 /// let _ = thread::spawn(move || {
393 /// let _lock = c_mutex.lock().unwrap();
394 /// panic!(); // the mutex gets poisoned
395 /// }).join();
396 ///
397 /// assert_eq!(mutex.is_poisoned(), true);
398 /// let x = mutex.lock().unwrap_or_else(|mut e| {
399 /// **e.get_mut() = 1;
400 /// mutex.clear_poison();
401 /// e.into_inner()
402 /// });
403 /// assert_eq!(mutex.is_poisoned(), false);
404 /// assert_eq!(*x, 1);
405 /// ```
406 #[inline]
407 #[stable(feature = "mutex_unpoison", since = "1.77.0")]
408 pub fn clear_poison(&self) {
409 self.poison.clear();
410 }
411
412 /// Consumes this mutex, returning the underlying data.
413 ///
414 /// # Errors
415 ///
416 /// If another user of this mutex panicked while holding the mutex, then
417 /// this call will return an error instead.
418 ///
419 /// # Examples
420 ///
421 /// ```
422 /// use std::sync::Mutex;
423 ///
424 /// let mutex = Mutex::new(0);
425 /// assert_eq!(mutex.into_inner().unwrap(), 0);
426 /// ```
427 #[stable(feature = "mutex_into_inner", since = "1.6.0")]
428 pub fn into_inner(self) -> LockResult<T>
429 where
430 T: Sized,
431 {
432 let data = self.data.into_inner();
433 poison::map_result(self.poison.borrow(), |()| data)
434 }
435
436 /// Returns a mutable reference to the underlying data.
437 ///
438 /// Since this call borrows the `Mutex` mutably, no actual locking needs to
439 /// take place -- the mutable borrow statically guarantees no locks exist.
440 ///
441 /// # Errors
442 ///
443 /// If another user of this mutex panicked while holding the mutex, then
444 /// this call will return an error instead.
445 ///
446 /// # Examples
447 ///
448 /// ```
449 /// use std::sync::Mutex;
450 ///
451 /// let mut mutex = Mutex::new(0);
452 /// *mutex.get_mut().unwrap() = 10;
453 /// assert_eq!(*mutex.lock().unwrap(), 10);
454 /// ```
455 #[stable(feature = "mutex_get_mut", since = "1.6.0")]
456 pub fn get_mut(&mut self) -> LockResult<&mut T> {
457 let data = self.data.get_mut();
458 poison::map_result(self.poison.borrow(), |()| data)
459 }
460}
461
462#[stable(feature = "mutex_from", since = "1.24.0")]
463impl<T> From<T> for Mutex<T> {
464 /// Creates a new mutex in an unlocked state ready for use.
465 /// This is equivalent to [`Mutex::new`].
466 fn from(t: T) -> Self {
467 Mutex::new(t)
468 }
469}
470
471#[stable(feature = "mutex_default", since = "1.10.0")]
472impl<T: ?Sized + Default> Default for Mutex<T> {
473 /// Creates a `Mutex<T>`, with the `Default` value for T.
474 fn default() -> Mutex<T> {
475 Mutex::new(Default::default())
476 }
477}
478
479#[stable(feature = "rust1", since = "1.0.0")]
480impl<T: ?Sized + fmt::Debug> fmt::Debug for Mutex<T> {
481 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
482 let mut d: DebugStruct<'_, '_> = f.debug_struct(name:"Mutex");
483 match self.try_lock() {
484 Ok(guard: MutexGuard<'_, T>) => {
485 d.field(name:"data", &&*guard);
486 }
487 Err(TryLockError::Poisoned(err: PoisonError>)) => {
488 d.field(name:"data", &&**err.get_ref());
489 }
490 Err(TryLockError::WouldBlock) => {
491 d.field(name:"data", &format_args!("<locked>"));
492 }
493 }
494 d.field(name:"poisoned", &self.poison.get());
495 d.finish_non_exhaustive()
496 }
497}
498
499impl<'mutex, T: ?Sized> MutexGuard<'mutex, T> {
500 unsafe fn new(lock: &'mutex Mutex<T>) -> LockResult<MutexGuard<'mutex, T>> {
501 poison::map_result(result:lock.poison.guard(), |guard: Guard| MutexGuard { lock, poison: guard })
502 }
503}
504
505#[stable(feature = "rust1", since = "1.0.0")]
506impl<T: ?Sized> Deref for MutexGuard<'_, T> {
507 type Target = T;
508
509 fn deref(&self) -> &T {
510 unsafe { &*self.lock.data.get() }
511 }
512}
513
514#[stable(feature = "rust1", since = "1.0.0")]
515impl<T: ?Sized> DerefMut for MutexGuard<'_, T> {
516 fn deref_mut(&mut self) -> &mut T {
517 unsafe { &mut *self.lock.data.get() }
518 }
519}
520
521#[stable(feature = "rust1", since = "1.0.0")]
522impl<T: ?Sized> Drop for MutexGuard<'_, T> {
523 #[inline]
524 fn drop(&mut self) {
525 unsafe {
526 self.lock.poison.done(&self.poison);
527 self.lock.inner.unlock();
528 }
529 }
530}
531
532#[stable(feature = "std_debug", since = "1.16.0")]
533impl<T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'_, T> {
534 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
535 fmt::Debug::fmt(&**self, f)
536 }
537}
538
539#[stable(feature = "std_guard_impls", since = "1.20.0")]
540impl<T: ?Sized + fmt::Display> fmt::Display for MutexGuard<'_, T> {
541 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
542 (**self).fmt(f)
543 }
544}
545
546pub fn guard_lock<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a sys::Mutex {
547 &guard.lock.inner
548}
549
550pub fn guard_poison<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a poison::Flag {
551 &guard.lock.poison
552}
553