]> git.proxmox.com Git - rustc.git/blame - library/std/src/sync/mutex.rs
New upstream version 1.48.0~beta.8+dfsg1
[rustc.git] / library / std / src / sync / mutex.rs
CommitLineData
1b1a35ee
XL
1#[cfg(all(test, not(target_os = "emscripten")))]
2mod tests;
3
532ac7d7
XL
4use crate::cell::UnsafeCell;
5use crate::fmt;
6use crate::mem;
7use crate::ops::{Deref, DerefMut};
8use crate::ptr;
9use crate::sys_common::mutex as sys;
dfeec247 10use crate::sys_common::poison::{self, LockResult, TryLockError, TryLockResult};
1a4d82fc
JJ
11
12/// A mutual exclusion primitive useful for protecting shared data
13///
14/// This mutex will block threads waiting for the lock to become available. The
ea8adc8c 15/// mutex can also be statically initialized or created via a [`new`]
1a4d82fc
JJ
16/// constructor. Each mutex has a type parameter which represents the data that
17/// it is protecting. The data can only be accessed through the RAII guards
ea8adc8c 18/// returned from [`lock`] and [`try_lock`], which guarantees that the data is only
1a4d82fc
JJ
19/// ever accessed when the mutex is locked.
20///
21/// # Poisoning
22///
23/// The mutexes in this module implement a strategy called "poisoning" where a
24/// mutex is considered poisoned whenever a thread panics while holding the
cc61c64b 25/// mutex. Once a mutex is poisoned, all other threads are unable to access the
1a4d82fc
JJ
26/// data by default as it is likely tainted (some invariant is not being
27/// upheld).
28///
ea8adc8c
XL
29/// For a mutex, this means that the [`lock`] and [`try_lock`] methods return a
30/// [`Result`] which indicates whether a mutex has been poisoned or not. Most
31/// usage of a mutex will simply [`unwrap()`] these results, propagating panics
1a4d82fc
JJ
32/// among threads to ensure that a possibly invalid invariant is not witnessed.
33///
34/// A poisoned mutex, however, does not prevent all access to the underlying
ea8adc8c 35/// data. The [`PoisonError`] type has an [`into_inner`] method which will return
1a4d82fc
JJ
36/// the guard that would have otherwise been returned on a successful lock. This
37/// allows access to the data, despite the lock being poisoned.
38///
3dfed10e
XL
39/// [`new`]: Self::new
40/// [`lock`]: Self::lock
41/// [`try_lock`]: Self::try_lock
42/// [`unwrap()`]: Result::unwrap
43/// [`PoisonError`]: super::PoisonError
44/// [`into_inner`]: super::PoisonError::into_inner
ea8adc8c 45///
1a4d82fc
JJ
46/// # Examples
47///
c34b1796 48/// ```
1a4d82fc 49/// use std::sync::{Arc, Mutex};
85aaf69f 50/// use std::thread;
1a4d82fc
JJ
51/// use std::sync::mpsc::channel;
52///
c34b1796 53/// const N: usize = 10;
1a4d82fc
JJ
54///
55/// // Spawn a few threads to increment a shared variable (non-atomically), and
56/// // let the main thread know once all increments are done.
57/// //
bd371182 58/// // Here we're using an Arc to share memory among threads, and the data inside
1a4d82fc
JJ
59/// // the Arc is protected with a mutex.
60/// let data = Arc::new(Mutex::new(0));
61///
62/// let (tx, rx) = channel();
cc61c64b 63/// for _ in 0..N {
a1dfa0c6 64/// let (data, tx) = (Arc::clone(&data), tx.clone());
85aaf69f 65/// thread::spawn(move || {
92a42be0 66/// // The shared state can only be accessed once the lock is held.
1a4d82fc
JJ
67/// // Our non-atomic increment is safe because we're the only thread
68/// // which can access the shared state when the lock is held.
69/// //
70/// // We unwrap() the return value to assert that we are not expecting
bd371182 71/// // threads to ever fail while holding the lock.
1a4d82fc
JJ
72/// let mut data = data.lock().unwrap();
73/// *data += 1;
74/// if *data == N {
75/// tx.send(()).unwrap();
76/// }
77/// // the lock is unlocked here when `data` goes out of scope.
78/// });
79/// }
80///
81/// rx.recv().unwrap();
82/// ```
83///
84/// To recover from a poisoned mutex:
85///
c34b1796 86/// ```
1a4d82fc 87/// use std::sync::{Arc, Mutex};
85aaf69f 88/// use std::thread;
1a4d82fc 89///
85aaf69f 90/// let lock = Arc::new(Mutex::new(0_u32));
1b1a35ee 91/// let lock2 = Arc::clone(&lock);
1a4d82fc 92///
85aaf69f 93/// let _ = thread::spawn(move || -> () {
1a4d82fc
JJ
94/// // This thread will acquire the mutex first, unwrapping the result of
95/// // `lock` because the lock has not been poisoned.
7453a54e 96/// let _guard = lock2.lock().unwrap();
1a4d82fc
JJ
97///
98/// // This panic while holding the lock (`_guard` is in scope) will poison
99/// // the mutex.
100/// panic!();
101/// }).join();
102///
103/// // The lock is poisoned by this point, but the returned result can be
104/// // pattern matched on to return the underlying guard on both branches.
105/// let mut guard = match lock.lock() {
106/// Ok(guard) => guard,
c34b1796 107/// Err(poisoned) => poisoned.into_inner(),
1a4d82fc
JJ
108/// };
109///
110/// *guard += 1;
111/// ```
f035d41b
XL
112///
113/// It is sometimes necessary to manually drop the mutex guard to unlock it
114/// sooner than the end of the enclosing scope.
115///
116/// ```
117/// use std::sync::{Arc, Mutex};
118/// use std::thread;
119///
120/// const N: usize = 3;
121///
122/// let data_mutex = Arc::new(Mutex::new(vec![1, 2, 3, 4]));
123/// let res_mutex = Arc::new(Mutex::new(0));
124///
125/// let mut threads = Vec::with_capacity(N);
126/// (0..N).for_each(|_| {
127/// let data_mutex_clone = Arc::clone(&data_mutex);
128/// let res_mutex_clone = Arc::clone(&res_mutex);
129///
130/// threads.push(thread::spawn(move || {
131/// let mut data = data_mutex_clone.lock().unwrap();
132/// // This is the result of some important and long-ish work.
133/// let result = data.iter().fold(0, |acc, x| acc + x * 2);
134/// data.push(result);
135/// drop(data);
136/// *res_mutex_clone.lock().unwrap() += result;
137/// }));
138/// });
139///
140/// let mut data = data_mutex.lock().unwrap();
141/// // This is the result of some important and long-ish work.
142/// let result = data.iter().fold(0, |acc, x| acc + x * 2);
143/// data.push(result);
144/// // We drop the `data` explicitly because it's not necessary anymore and the
145/// // thread still has work to do. This allow other threads to start working on
146/// // the data immediately, without waiting for the rest of the unrelated work
147/// // to be done here.
148/// //
149/// // It's even more important here than in the threads because we `.join` the
150/// // threads after that. If we had not dropped the mutex guard, a thread could
151/// // be waiting forever for it, causing a deadlock.
152/// drop(data);
153/// // Here the mutex guard is not assigned to a variable and so, even if the
154/// // scope does not end after this line, the mutex is still released: there is
155/// // no deadlock.
156/// *res_mutex.lock().unwrap() += result;
157///
158/// threads.into_iter().for_each(|thread| {
159/// thread
160/// .join()
161/// .expect("The thread creating or execution failed !")
162/// });
163///
164/// assert_eq!(*res_mutex.lock().unwrap(), 800);
165/// ```
85aaf69f 166#[stable(feature = "rust1", since = "1.0.0")]
f9f354fc 167#[cfg_attr(not(test), rustc_diagnostic_item = "mutex_type")]
d9579d0f 168pub struct Mutex<T: ?Sized> {
1b1a35ee 169 inner: sys::MovableMutex,
5bcae85e 170 poison: poison::Flag,
1a4d82fc
JJ
171 data: UnsafeCell<T>,
172}
173
c34b1796
AL
174// these are the only places where `T: Send` matters; all other
175// functionality works fine on a single thread.
92a42be0 176#[stable(feature = "rust1", since = "1.0.0")]
dfeec247 177unsafe impl<T: ?Sized + Send> Send for Mutex<T> {}
92a42be0 178#[stable(feature = "rust1", since = "1.0.0")]
dfeec247 179unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
1a4d82fc 180
1a4d82fc
JJ
181/// An RAII implementation of a "scoped lock" of a mutex. When this structure is
182/// dropped (falls out of scope), the lock will be unlocked.
183///
cc61c64b 184/// The data protected by the mutex can be accessed through this guard via its
8bb4bdeb 185/// [`Deref`] and [`DerefMut`] implementations.
476ff2be 186///
cc61c64b 187/// This structure is created by the [`lock`] and [`try_lock`] methods on
476ff2be
SL
188/// [`Mutex`].
189///
3dfed10e
XL
190/// [`lock`]: Mutex::lock
191/// [`try_lock`]: Mutex::try_lock
94b46f34 192#[must_use = "if unused the Mutex will immediately unlock"]
85aaf69f 193#[stable(feature = "rust1", since = "1.0.0")]
d9579d0f 194pub struct MutexGuard<'a, T: ?Sized + 'a> {
60c5eb7d
XL
195 lock: &'a Mutex<T>,
196 poison: poison::Guard,
1a4d82fc
JJ
197}
198
92a42be0 199#[stable(feature = "rust1", since = "1.0.0")]
dfeec247 200impl<T: ?Sized> !Send for MutexGuard<'_, T> {}
7cac9316 201#[stable(feature = "mutexguard", since = "1.19.0")]
dfeec247 202unsafe impl<T: ?Sized + Sync> Sync for MutexGuard<'_, T> {}
85aaf69f 203
c34b1796 204impl<T> Mutex<T> {
1a4d82fc 205 /// Creates a new mutex in an unlocked state ready for use.
32a655c1
SL
206 ///
207 /// # Examples
208 ///
209 /// ```
210 /// use std::sync::Mutex;
211 ///
212 /// let mutex = Mutex::new(0);
213 /// ```
85aaf69f 214 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 215 pub fn new(t: T) -> Mutex<T> {
1b1a35ee
XL
216 Mutex {
217 inner: sys::MovableMutex::new(),
5bcae85e 218 poison: poison::Flag::new(),
1a4d82fc
JJ
219 data: UnsafeCell::new(t),
220 }
221 }
d9579d0f 222}
1a4d82fc 223
d9579d0f 224impl<T: ?Sized> Mutex<T> {
bd371182 225 /// Acquires a mutex, blocking the current thread until it is able to do so.
1a4d82fc 226 ///
bd371182 227 /// This function will block the local thread until it is available to acquire
cc61c64b 228 /// the mutex. Upon returning, the thread is the only thread with the lock
1a4d82fc
JJ
229 /// held. An RAII guard is returned to allow scoped unlock of the lock. When
230 /// the guard goes out of scope, the mutex will be unlocked.
231 ///
a7813a04
XL
232 /// The exact behavior on locking a mutex in the thread which already holds
233 /// the lock is left unspecified. However, this function will not return on
234 /// the second call (it might panic or deadlock, for example).
235 ///
7453a54e 236 /// # Errors
1a4d82fc
JJ
237 ///
238 /// If another user of this mutex panicked while holding the mutex, then
239 /// this call will return an error once the mutex is acquired.
a7813a04
XL
240 ///
241 /// # Panics
242 ///
243 /// This function might panic when called if the lock is already held by
244 /// the current thread.
32a655c1
SL
245 ///
246 /// # Examples
247 ///
248 /// ```
249 /// use std::sync::{Arc, Mutex};
250 /// use std::thread;
251 ///
252 /// let mutex = Arc::new(Mutex::new(0));
1b1a35ee 253 /// let c_mutex = Arc::clone(&mutex);
32a655c1
SL
254 ///
255 /// thread::spawn(move || {
256 /// *c_mutex.lock().unwrap() = 10;
257 /// }).join().expect("thread::spawn failed");
258 /// assert_eq!(*mutex.lock().unwrap(), 10);
259 /// ```
85aaf69f 260 #[stable(feature = "rust1", since = "1.0.0")]
532ac7d7 261 pub fn lock(&self) -> LockResult<MutexGuard<'_, T>> {
7453a54e 262 unsafe {
94b46f34 263 self.inner.raw_lock();
5bcae85e 264 MutexGuard::new(self)
7453a54e 265 }
1a4d82fc
JJ
266 }
267
268 /// Attempts to acquire this lock.
269 ///
ea8adc8c 270 /// If the lock could not be acquired at this time, then [`Err`] is returned.
1a4d82fc
JJ
271 /// Otherwise, an RAII guard is returned. The lock will be unlocked when the
272 /// guard is dropped.
273 ///
274 /// This function does not block.
275 ///
7453a54e 276 /// # Errors
1a4d82fc
JJ
277 ///
278 /// If another user of this mutex panicked while holding the mutex, then
279 /// this call will return failure if the mutex would otherwise be
280 /// acquired.
32a655c1
SL
281 ///
282 /// # Examples
283 ///
284 /// ```
285 /// use std::sync::{Arc, Mutex};
286 /// use std::thread;
287 ///
288 /// let mutex = Arc::new(Mutex::new(0));
1b1a35ee 289 /// let c_mutex = Arc::clone(&mutex);
32a655c1
SL
290 ///
291 /// thread::spawn(move || {
292 /// let mut lock = c_mutex.try_lock();
293 /// if let Ok(ref mut mutex) = lock {
294 /// **mutex = 10;
295 /// } else {
296 /// println!("try_lock failed");
297 /// }
298 /// }).join().expect("thread::spawn failed");
299 /// assert_eq!(*mutex.lock().unwrap(), 10);
300 /// ```
85aaf69f 301 #[stable(feature = "rust1", since = "1.0.0")]
532ac7d7 302 pub fn try_lock(&self) -> TryLockResult<MutexGuard<'_, T>> {
7453a54e 303 unsafe {
5bcae85e
SL
304 if self.inner.try_lock() {
305 Ok(MutexGuard::new(self)?)
7453a54e
SL
306 } else {
307 Err(TryLockError::WouldBlock)
308 }
1a4d82fc
JJ
309 }
310 }
85aaf69f 311
cc61c64b 312 /// Determines whether the mutex is poisoned.
85aaf69f 313 ///
cc61c64b 314 /// If another thread is active, the mutex can still become poisoned at any
32a655c1 315 /// time. You should not trust a `false` value for program correctness
85aaf69f 316 /// without additional synchronization.
32a655c1
SL
317 ///
318 /// # Examples
319 ///
320 /// ```
321 /// use std::sync::{Arc, Mutex};
322 /// use std::thread;
323 ///
324 /// let mutex = Arc::new(Mutex::new(0));
1b1a35ee 325 /// let c_mutex = Arc::clone(&mutex);
32a655c1
SL
326 ///
327 /// let _ = thread::spawn(move || {
328 /// let _lock = c_mutex.lock().unwrap();
329 /// panic!(); // the mutex gets poisoned
330 /// }).join();
331 /// assert_eq!(mutex.is_poisoned(), true);
332 /// ```
85aaf69f 333 #[inline]
62682a34 334 #[stable(feature = "sync_poison", since = "1.2.0")]
85aaf69f 335 pub fn is_poisoned(&self) -> bool {
5bcae85e 336 self.poison.get()
85aaf69f 337 }
b039eaaf
SL
338
339 /// Consumes this mutex, returning the underlying data.
340 ///
7453a54e 341 /// # Errors
b039eaaf
SL
342 ///
343 /// If another user of this mutex panicked while holding the mutex, then
344 /// this call will return an error instead.
32a655c1
SL
345 ///
346 /// # Examples
347 ///
348 /// ```
349 /// use std::sync::Mutex;
350 ///
351 /// let mutex = Mutex::new(0);
352 /// assert_eq!(mutex.into_inner().unwrap(), 0);
353 /// ```
92a42be0 354 #[stable(feature = "mutex_into_inner", since = "1.6.0")]
dfeec247
XL
355 pub fn into_inner(self) -> LockResult<T>
356 where
357 T: Sized,
358 {
b039eaaf 359 // We know statically that there are no outstanding references to
cc61c64b 360 // `self` so there's no need to lock the inner mutex.
b039eaaf
SL
361 //
362 // To get the inner value, we'd like to call `data.into_inner()`,
363 // but because `Mutex` impl-s `Drop`, we can't move out of it, so
364 // we'll have to destructure it manually instead.
365 unsafe {
5bcae85e
SL
366 // Like `let Mutex { inner, poison, data } = self`.
367 let (inner, poison, data) = {
368 let Mutex { ref inner, ref poison, ref data } = self;
369 (ptr::read(inner), ptr::read(poison), ptr::read(data))
b039eaaf
SL
370 };
371 mem::forget(self);
5bcae85e 372 drop(inner);
b039eaaf 373
5bcae85e 374 poison::map_result(poison.borrow(), |_| data.into_inner())
b039eaaf
SL
375 }
376 }
377
378 /// Returns a mutable reference to the underlying data.
379 ///
380 /// Since this call borrows the `Mutex` mutably, no actual locking needs to
9fa01778 381 /// take place -- the mutable borrow statically guarantees no locks exist.
b039eaaf 382 ///
7453a54e 383 /// # Errors
b039eaaf
SL
384 ///
385 /// If another user of this mutex panicked while holding the mutex, then
386 /// this call will return an error instead.
32a655c1
SL
387 ///
388 /// # Examples
389 ///
390 /// ```
391 /// use std::sync::Mutex;
392 ///
393 /// let mut mutex = Mutex::new(0);
394 /// *mutex.get_mut().unwrap() = 10;
395 /// assert_eq!(*mutex.lock().unwrap(), 10);
396 /// ```
92a42be0 397 #[stable(feature = "mutex_get_mut", since = "1.6.0")]
b039eaaf 398 pub fn get_mut(&mut self) -> LockResult<&mut T> {
1b1a35ee 399 let data = self.data.get_mut();
dfeec247 400 poison::map_result(self.poison.borrow(), |_| data)
b039eaaf 401 }
1a4d82fc
JJ
402}
403
2c00a5a8 404#[stable(feature = "mutex_from", since = "1.24.0")]
ff7c6d11
XL
405impl<T> From<T> for Mutex<T> {
406 /// Creates a new mutex in an unlocked state ready for use.
407 /// This is equivalent to [`Mutex::new`].
ff7c6d11
XL
408 fn from(t: T) -> Self {
409 Mutex::new(t)
410 }
411}
412
7cac9316 413#[stable(feature = "mutex_default", since = "1.10.0")]
a7813a04 414impl<T: ?Sized + Default> Default for Mutex<T> {
9e0c209e 415 /// Creates a `Mutex<T>`, with the `Default` value for T.
a7813a04
XL
416 fn default() -> Mutex<T> {
417 Mutex::new(Default::default())
418 }
419}
420
c34b1796 421#[stable(feature = "rust1", since = "1.0.0")]
7453a54e 422impl<T: ?Sized + fmt::Debug> fmt::Debug for Mutex<T> {
532ac7d7 423 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
c34b1796 424 match self.try_lock() {
abe05a73 425 Ok(guard) => f.debug_struct("Mutex").field("data", &&*guard).finish(),
c34b1796 426 Err(TryLockError::Poisoned(err)) => {
abe05a73 427 f.debug_struct("Mutex").field("data", &&**err.get_ref()).finish()
dfeec247 428 }
abe05a73
XL
429 Err(TryLockError::WouldBlock) => {
430 struct LockedPlaceholder;
431 impl fmt::Debug for LockedPlaceholder {
532ac7d7
XL
432 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
433 f.write_str("<locked>")
434 }
abe05a73
XL
435 }
436
437 f.debug_struct("Mutex").field("data", &LockedPlaceholder).finish()
438 }
c34b1796
AL
439 }
440 }
441}
442
d9579d0f 443impl<'mutex, T: ?Sized> MutexGuard<'mutex, T> {
5bcae85e 444 unsafe fn new(lock: &'mutex Mutex<T>) -> LockResult<MutexGuard<'mutex, T>> {
74b04a01 445 poison::map_result(lock.poison.borrow(), |guard| MutexGuard { lock, poison: guard })
1a4d82fc
JJ
446 }
447}
448
85aaf69f 449#[stable(feature = "rust1", since = "1.0.0")]
9fa01778 450impl<T: ?Sized> Deref for MutexGuard<'_, T> {
1a4d82fc
JJ
451 type Target = T;
452
5bcae85e 453 fn deref(&self) -> &T {
60c5eb7d 454 unsafe { &*self.lock.data.get() }
5bcae85e 455 }
1a4d82fc 456}
e9174d1e 457
85aaf69f 458#[stable(feature = "rust1", since = "1.0.0")]
9fa01778 459impl<T: ?Sized> DerefMut for MutexGuard<'_, T> {
5bcae85e 460 fn deref_mut(&mut self) -> &mut T {
60c5eb7d 461 unsafe { &mut *self.lock.data.get() }
5bcae85e 462 }
1a4d82fc
JJ
463}
464
85aaf69f 465#[stable(feature = "rust1", since = "1.0.0")]
9fa01778 466impl<T: ?Sized> Drop for MutexGuard<'_, T> {
1a4d82fc
JJ
467 #[inline]
468 fn drop(&mut self) {
469 unsafe {
60c5eb7d
XL
470 self.lock.poison.done(&self.poison);
471 self.lock.inner.raw_unlock();
1a4d82fc
JJ
472 }
473 }
474}
475
8bb4bdeb 476#[stable(feature = "std_debug", since = "1.16.0")]
9fa01778 477impl<T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'_, T> {
532ac7d7 478 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9fa01778 479 fmt::Debug::fmt(&**self, f)
32a655c1
SL
480 }
481}
482
041b39d2 483#[stable(feature = "std_guard_impls", since = "1.20.0")]
9fa01778 484impl<T: ?Sized + fmt::Display> fmt::Display for MutexGuard<'_, T> {
532ac7d7 485 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
041b39d2
XL
486 (**self).fmt(f)
487 }
488}
489
1b1a35ee 490pub fn guard_lock<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a sys::MovableMutex {
60c5eb7d 491 &guard.lock.inner
1a4d82fc
JJ
492}
493
d9579d0f 494pub fn guard_poison<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a poison::Flag {
60c5eb7d 495 &guard.lock.poison
1a4d82fc 496}