@@ -9,18 +9,15 @@ use crate::ops::{Deref, DerefMut};
99use crate :: ptr:: NonNull ;
1010use crate :: sys:: sync as sys;
1111
12- /// A mutual exclusion primitive useful for protecting shared data
12+ /// A mutual exclusion primitive useful for protecting shared data.
13+ ///
14+ /// For more information about mutexes, check out the documentation for the
15+ /// poisoning variant of this lock found at [std::sync::poison::Mutex](std::sync::nonpoison::Mutex).
1316///
14- /// This mutex will block threads waiting for the lock to become available. The
15- /// mutex can be created via a [`new`] constructor. Each mutex has a type parameter
16- /// which represents the data that it is protecting. The data can only be accessed
17- /// through the RAII guards returned from [`lock`] and [`try_lock`], which
18- /// guarantees that the data is only ever accessed when the mutex is locked.
19- ///
20- /// # Examples
17+ /// # Example
2118///
2219/// ```
23- /// use std::sync::{Arc, Mutex};
20+ /// use std::sync::{Arc, nonpoison:: Mutex};
2421/// use std::thread;
2522/// use std::sync::mpsc::channel;
2623///
@@ -40,10 +37,8 @@ use crate::sys::sync as sys;
4037/// // The shared state can only be accessed once the lock is held.
4138/// // Our non-atomic increment is safe because we're the only thread
4239/// // which can access the shared state when the lock is held.
43- /// //
44- /// // We unwrap() the return value to assert that we are not expecting
45- /// // threads to ever fail while holding the lock.
46- /// let mut data = data.lock().unwrap();
40+ ///
41+ /// let mut data = data.lock();
4742/// *data += 1;
4843/// if *data == N {
4944/// tx.send(()).unwrap();
@@ -55,98 +50,6 @@ use crate::sys::sync as sys;
5550/// rx.recv().unwrap();
5651/// ```
5752///
58- /// To recover from a poisoned mutex:
59- ///
60- /// ```
61- /// use std::sync::{Arc, Mutex};
62- /// use std::thread;
63- ///
64- /// let lock = Arc::new(Mutex::new(0_u32));
65- /// let lock2 = Arc::clone(&lock);
66- ///
67- /// let _ = thread::spawn(move || -> () {
68- /// // This thread will acquire the mutex first, unwrapping the result of
69- /// // `lock` because the lock has not been poisoned.
70- /// let _guard = lock2.lock().unwrap();
71- ///
72- /// // This panic while holding the lock (`_guard` is in scope) will poison
73- /// // the mutex.
74- /// panic!();
75- /// }).join();
76- ///
77- /// // The lock is poisoned by this point, but the returned result can be
78- /// // pattern matched on to return the underlying guard on both branches.
79- /// let mut guard = match lock.lock() {
80- /// Ok(guard) => guard,
81- /// Err(poisoned) => poisoned.into_inner(),
82- /// };
83- ///
84- /// *guard += 1;
85- /// ```
86- ///
87- /// To unlock a mutex guard sooner than the end of the enclosing scope,
88- /// either create an inner scope or drop the guard manually.
89- ///
90- /// ```
91- /// use std::sync::{Arc, Mutex};
92- /// use std::thread;
93- ///
94- /// const N: usize = 3;
95- ///
96- /// let data_mutex = Arc::new(Mutex::new(vec![1, 2, 3, 4]));
97- /// let res_mutex = Arc::new(Mutex::new(0));
98- ///
99- /// let mut threads = Vec::with_capacity(N);
100- /// (0..N).for_each(|_| {
101- /// let data_mutex_clone = Arc::clone(&data_mutex);
102- /// let res_mutex_clone = Arc::clone(&res_mutex);
103- ///
104- /// threads.push(thread::spawn(move || {
105- /// // Here we use a block to limit the lifetime of the lock guard.
106- /// let result = {
107- /// let mut data = data_mutex_clone.lock().unwrap();
108- /// // This is the result of some important and long-ish work.
109- /// let result = data.iter().fold(0, |acc, x| acc + x * 2);
110- /// data.push(result);
111- /// result
112- /// // The mutex guard gets dropped here, together with any other values
113- /// // created in the critical section.
114- /// };
115- /// // The guard created here is a temporary dropped at the end of the statement, i.e.
116- /// // the lock would not remain being held even if the thread did some additional work.
117- /// *res_mutex_clone.lock().unwrap() += result;
118- /// }));
119- /// });
120- ///
121- /// let mut data = data_mutex.lock().unwrap();
122- /// // This is the result of some important and long-ish work.
123- /// let result = data.iter().fold(0, |acc, x| acc + x * 2);
124- /// data.push(result);
125- /// // We drop the `data` explicitly because it's not necessary anymore and the
126- /// // thread still has work to do. This allows other threads to start working on
127- /// // the data immediately, without waiting for the rest of the unrelated work
128- /// // to be done here.
129- /// //
130- /// // It's even more important here than in the threads because we `.join` the
131- /// // threads after that. If we had not dropped the mutex guard, a thread could
132- /// // be waiting forever for it, causing a deadlock.
133- /// // As in the threads, a block could have been used instead of calling the
134- /// // `drop` function.
135- /// drop(data);
136- /// // Here the mutex guard is not assigned to a variable and so, even if the
137- /// // scope does not end after this line, the mutex is still released: there is
138- /// // no deadlock.
139- /// *res_mutex.lock().unwrap() += result;
140- ///
141- /// threads.into_iter().for_each(|thread| {
142- /// thread
143- /// .join()
144- /// .expect("The thread creating or execution failed !")
145- /// });
146- ///
147- /// assert_eq!(*res_mutex.lock().unwrap(), 800);
148- /// ```
149- ///
15053#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
15154#[ cfg_attr( not( test) , rustc_diagnostic_item = "NonPoisonMutex" ) ]
15255pub struct Mutex < T : ?Sized > {
@@ -233,7 +136,7 @@ impl<T> Mutex<T> {
233136 /// # Examples
234137 ///
235138 /// ```
236- /// use std::sync::Mutex;
139+ /// use std::sync::nonpoison:: Mutex;
237140 ///
238141 /// let mutex = Mutex::new(0);
239142 /// ```
@@ -256,12 +159,6 @@ impl<T: ?Sized> Mutex<T> {
256159 /// the lock is left unspecified. However, this function will not return on
257160 /// the second call (it might panic or deadlock, for example).
258161 ///
259- /// # Errors
260- ///
261- /// If another user of this mutex panicked while holding the mutex, then
262- /// this call will return an error once the mutex is acquired. The acquired
263- /// mutex guard will be contained in the returned error.
264- ///
265162 /// # Panics
266163 ///
267164 /// This function might panic when called if the lock is already held by
@@ -270,16 +167,16 @@ impl<T: ?Sized> Mutex<T> {
270167 /// # Examples
271168 ///
272169 /// ```
273- /// use std::sync::{Arc, Mutex};
170+ /// use std::sync::{Arc, nonpoison:: Mutex};
274171 /// use std::thread;
275172 ///
276173 /// let mutex = Arc::new(Mutex::new(0));
277174 /// let c_mutex = Arc::clone(&mutex);
278175 ///
279176 /// thread::spawn(move || {
280- /// *c_mutex.lock().unwrap() = 10;
177+ /// *c_mutex.lock() = 10;
281178 /// }).join().expect("thread::spawn failed");
282- /// assert_eq!(*mutex.lock().unwrap() , 10);
179+ /// assert_eq!(*mutex.lock(), 10);
283180 /// ```
284181 #[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
285182 pub fn lock ( & self ) -> MutexGuard < ' _ , T > {
@@ -291,43 +188,35 @@ impl<T: ?Sized> Mutex<T> {
291188
292189 /// Attempts to acquire this lock.
293190 ///
294- /// If the lock could not be acquired at this time, then [`Err `] is returned.
191+ /// If the lock could not be acquired at this time, then [`None `] is returned.
295192 /// Otherwise, an RAII guard is returned. The lock will be unlocked when the
296193 /// guard is dropped.
297194 ///
298195 /// This function does not block.
299196 ///
300197 /// # Errors
301198 ///
302- /// If another user of this mutex panicked while holding the mutex, then
303- /// this call will return the [`Poisoned`] error if the mutex would
304- /// otherwise be acquired. An acquired lock guard will be contained
305- /// in the returned error.
306- ///
307199 /// If the mutex could not be acquired because it is already locked, then
308- /// this call will return the [`WouldBlock`] error.
309- ///
310- /// [`Poisoned`]: TryLockError::Poisoned
311- /// [`WouldBlock`]: TryLockError::WouldBlock
200+ /// this call will return [`None`].
312201 ///
313202 /// # Examples
314203 ///
315204 /// ```
316- /// use std::sync::{Arc, Mutex};
205+ /// use std::sync::{Arc, nonpoison:: Mutex};
317206 /// use std::thread;
318207 ///
319208 /// let mutex = Arc::new(Mutex::new(0));
320209 /// let c_mutex = Arc::clone(&mutex);
321210 ///
322211 /// thread::spawn(move || {
323212 /// let mut lock = c_mutex.try_lock();
324- /// if let Ok (ref mut mutex) = lock {
213+ /// if let Some (ref mut mutex) = lock {
325214 /// **mutex = 10;
326215 /// } else {
327216 /// println!("try_lock failed");
328217 /// }
329218 /// }).join().expect("thread::spawn failed");
330- /// assert_eq!(*mutex.lock().unwrap() , 10);
219+ /// assert_eq!(*mutex.lock(), 10);
331220 /// ```
332221 #[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
333222 pub fn try_lock ( & self ) -> Option < MutexGuard < ' _ , T > > {
@@ -336,19 +225,13 @@ impl<T: ?Sized> Mutex<T> {
336225
337226 /// Consumes this mutex, returning the underlying data.
338227 ///
339- /// # Errors
340- ///
341- /// If another user of this mutex panicked while holding the mutex, then
342- /// this call will return an error containing the the underlying data
343- /// instead.
344- ///
345228 /// # Examples
346229 ///
347230 /// ```
348- /// use std::sync::Mutex;
231+ /// use std::sync::nonpoison:: Mutex;
349232 ///
350233 /// let mutex = Mutex::new(0);
351- /// assert_eq!(mutex.into_inner().unwrap() , 0);
234+ /// assert_eq!(mutex.into_inner(), 0);
352235 /// ```
353236 #[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
354237 #[ inline]
@@ -364,20 +247,14 @@ impl<T: ?Sized> Mutex<T> {
364247 /// Since this call borrows the `Mutex` mutably, no actual locking needs to
365248 /// take place -- the mutable borrow statically guarantees no locks exist.
366249 ///
367- /// # Errors
368- ///
369- /// If another user of this mutex panicked while holding the mutex, then
370- /// this call will return an error containing a mutable reference to the
371- /// underlying data instead.
372- ///
373250 /// # Examples
374251 ///
375252 /// ```
376- /// use std::sync::Mutex;
253+ /// use std::sync::nonpoison:: Mutex;
377254 ///
378255 /// let mut mutex = Mutex::new(0);
379- /// *mutex.get_mut().unwrap() = 10;
380- /// assert_eq!(*mutex.lock().unwrap() , 10);
256+ /// *mutex.get_mut() = 10;
257+ /// assert_eq!(*mutex.lock(), 10);
381258 /// ```
382259 #[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
383260 #[ inline]
0 commit comments