1 | use crate::cell::UnsafeCell; |
2 | use crate::fmt; |
3 | use crate::marker::PhantomData; |
4 | use crate::mem::{self, ManuallyDrop}; |
5 | use crate::ops::{Deref, DerefMut}; |
6 | use crate::ptr::NonNull; |
7 | use crate::sync::{LockResult, PoisonError, TryLockError, TryLockResult, poison}; |
8 | use 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" )] |
175 | pub 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" )] |
186 | unsafe 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" )] |
205 | unsafe 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" )] |
225 | pub 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" )] |
237 | impl<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" )] |
242 | unsafe 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] |
268 | pub 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" )] |
281 | impl<T: ?Sized> !Send for MappedMutexGuard<'_, T> {} |
282 | #[unstable (feature = "mapped_lock_guards" , issue = "117108" )] |
283 | unsafe impl<T: ?Sized + Sync> Sync for MappedMutexGuard<'_, T> {} |
284 | |
285 | impl<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 | |
397 | impl<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" )] |
610 | impl<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" )] |
619 | impl<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" )] |
627 | impl<T: ?Sized + fmt::Debug> fmt::Debug for Mutex<T> { |
628 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
629 | let mut d: DebugStruct<'_, '_> = f.debug_struct(name:"Mutex" ); |
630 | match self.try_lock() { |
631 | Ok(guard: MutexGuard<'_, T>) => { |
632 | d.field(name:"data" , &&*guard); |
633 | } |
634 | Err(TryLockError::Poisoned(err: PoisonError>)) => { |
635 | d.field(name:"data" , &&**err.get_ref()); |
636 | } |
637 | Err(TryLockError::WouldBlock) => { |
638 | d.field(name:"data" , &format_args!("<locked>" )); |
639 | } |
640 | } |
641 | d.field(name:"poisoned" , &self.poison.get()); |
642 | d.finish_non_exhaustive() |
643 | } |
644 | } |
645 | |
646 | impl<'mutex, T: ?Sized> MutexGuard<'mutex, T> { |
647 | unsafe fn new(lock: &'mutex Mutex<T>) -> LockResult<MutexGuard<'mutex, T>> { |
648 | poison::map_result(result:lock.poison.guard(), |guard: Guard| MutexGuard { lock, poison: guard }) |
649 | } |
650 | } |
651 | |
652 | #[stable (feature = "rust1" , since = "1.0.0" )] |
653 | impl<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" )] |
662 | impl<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" )] |
669 | impl<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" )] |
680 | impl<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" )] |
687 | impl<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 | |
693 | pub fn guard_lock<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a sys::Mutex { |
694 | &guard.lock.inner |
695 | } |
696 | |
697 | pub fn guard_poison<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a poison::Flag { |
698 | &guard.lock.poison |
699 | } |
700 | |
701 | impl<'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" )] |
769 | impl<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" )] |
778 | impl<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" )] |
785 | impl<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" )] |
796 | impl<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" )] |
803 | impl<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 | |
809 | impl<'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 | } |
875 | |