@@ -9,18 +9,15 @@ use crate::ops::{Deref, DerefMut};
9
9
use crate :: ptr:: NonNull ;
10
10
use crate :: sys:: sync as sys;
11
11
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).
13
16
///
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
21
18
///
22
19
/// ```
23
- /// use std::sync::{Arc, Mutex};
20
+ /// use std::sync::{Arc, nonpoison:: Mutex};
24
21
/// use std::thread;
25
22
/// use std::sync::mpsc::channel;
26
23
///
@@ -40,10 +37,8 @@ use crate::sys::sync as sys;
40
37
/// // The shared state can only be accessed once the lock is held.
41
38
/// // Our non-atomic increment is safe because we're the only thread
42
39
/// // 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();
47
42
/// *data += 1;
48
43
/// if *data == N {
49
44
/// tx.send(()).unwrap();
@@ -55,98 +50,6 @@ use crate::sys::sync as sys;
55
50
/// rx.recv().unwrap();
56
51
/// ```
57
52
///
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
- ///
150
53
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
151
54
#[ cfg_attr( not( test) , rustc_diagnostic_item = "NonPoisonMutex" ) ]
152
55
pub struct Mutex < T : ?Sized > {
@@ -233,7 +136,7 @@ impl<T> Mutex<T> {
233
136
/// # Examples
234
137
///
235
138
/// ```
236
- /// use std::sync::Mutex;
139
+ /// use std::sync::nonpoison:: Mutex;
237
140
///
238
141
/// let mutex = Mutex::new(0);
239
142
/// ```
@@ -256,12 +159,6 @@ impl<T: ?Sized> Mutex<T> {
256
159
/// the lock is left unspecified. However, this function will not return on
257
160
/// the second call (it might panic or deadlock, for example).
258
161
///
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
- ///
265
162
/// # Panics
266
163
///
267
164
/// This function might panic when called if the lock is already held by
@@ -270,16 +167,16 @@ impl<T: ?Sized> Mutex<T> {
270
167
/// # Examples
271
168
///
272
169
/// ```
273
- /// use std::sync::{Arc, Mutex};
170
+ /// use std::sync::{Arc, nonpoison:: Mutex};
274
171
/// use std::thread;
275
172
///
276
173
/// let mutex = Arc::new(Mutex::new(0));
277
174
/// let c_mutex = Arc::clone(&mutex);
278
175
///
279
176
/// thread::spawn(move || {
280
- /// *c_mutex.lock().unwrap() = 10;
177
+ /// *c_mutex.lock() = 10;
281
178
/// }).join().expect("thread::spawn failed");
282
- /// assert_eq!(*mutex.lock().unwrap() , 10);
179
+ /// assert_eq!(*mutex.lock(), 10);
283
180
/// ```
284
181
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
285
182
pub fn lock ( & self ) -> MutexGuard < ' _ , T > {
@@ -291,43 +188,35 @@ impl<T: ?Sized> Mutex<T> {
291
188
292
189
/// Attempts to acquire this lock.
293
190
///
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.
295
192
/// Otherwise, an RAII guard is returned. The lock will be unlocked when the
296
193
/// guard is dropped.
297
194
///
298
195
/// This function does not block.
299
196
///
300
197
/// # Errors
301
198
///
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
- ///
307
199
/// 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`].
312
201
///
313
202
/// # Examples
314
203
///
315
204
/// ```
316
- /// use std::sync::{Arc, Mutex};
205
+ /// use std::sync::{Arc, nonpoison:: Mutex};
317
206
/// use std::thread;
318
207
///
319
208
/// let mutex = Arc::new(Mutex::new(0));
320
209
/// let c_mutex = Arc::clone(&mutex);
321
210
///
322
211
/// thread::spawn(move || {
323
212
/// let mut lock = c_mutex.try_lock();
324
- /// if let Ok (ref mut mutex) = lock {
213
+ /// if let Some (ref mut mutex) = lock {
325
214
/// **mutex = 10;
326
215
/// } else {
327
216
/// println!("try_lock failed");
328
217
/// }
329
218
/// }).join().expect("thread::spawn failed");
330
- /// assert_eq!(*mutex.lock().unwrap() , 10);
219
+ /// assert_eq!(*mutex.lock(), 10);
331
220
/// ```
332
221
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
333
222
pub fn try_lock ( & self ) -> Option < MutexGuard < ' _ , T > > {
@@ -336,19 +225,13 @@ impl<T: ?Sized> Mutex<T> {
336
225
337
226
/// Consumes this mutex, returning the underlying data.
338
227
///
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
- ///
345
228
/// # Examples
346
229
///
347
230
/// ```
348
- /// use std::sync::Mutex;
231
+ /// use std::sync::nonpoison:: Mutex;
349
232
///
350
233
/// let mutex = Mutex::new(0);
351
- /// assert_eq!(mutex.into_inner().unwrap() , 0);
234
+ /// assert_eq!(mutex.into_inner(), 0);
352
235
/// ```
353
236
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
354
237
#[ inline]
@@ -364,20 +247,14 @@ impl<T: ?Sized> Mutex<T> {
364
247
/// Since this call borrows the `Mutex` mutably, no actual locking needs to
365
248
/// take place -- the mutable borrow statically guarantees no locks exist.
366
249
///
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
- ///
373
250
/// # Examples
374
251
///
375
252
/// ```
376
- /// use std::sync::Mutex;
253
+ /// use std::sync::nonpoison:: Mutex;
377
254
///
378
255
/// 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);
381
258
/// ```
382
259
#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
383
260
#[ inline]
0 commit comments