@@ -4,10 +4,10 @@ mod tests;
4
4
use crate :: cell:: UnsafeCell ;
5
5
use crate :: fmt;
6
6
use crate :: marker:: PhantomData ;
7
- use crate :: mem:: ManuallyDrop ;
7
+ use crate :: mem:: { self , ManuallyDrop } ;
8
8
use crate :: ops:: { Deref , DerefMut } ;
9
9
use crate :: ptr:: NonNull ;
10
- use crate :: sync:: { LockResult , TryLockError , TryLockResult , poison} ;
10
+ use crate :: sync:: { LockResult , PoisonError , TryLockError , TryLockResult , poison} ;
11
11
use crate :: sys:: sync as sys;
12
12
13
13
/// A mutual exclusion primitive useful for protecting shared data
@@ -273,6 +273,100 @@ impl<T> Mutex<T> {
273
273
pub const fn new ( t : T ) -> Mutex < T > {
274
274
Mutex { inner : sys:: Mutex :: new ( ) , poison : poison:: Flag :: new ( ) , data : UnsafeCell :: new ( t) }
275
275
}
276
+
277
+ /// Returns the contained value by cloning it.
278
+ ///
279
+ /// # Errors
280
+ ///
281
+ /// If another user of this mutex panicked while holding the mutex, then
282
+ /// this call will return an error instead.
283
+ ///
284
+ /// # Examples
285
+ ///
286
+ /// ```
287
+ /// #![feature(lock_value_accessors)]
288
+ ///
289
+ /// use std::sync::Mutex;
290
+ ///
291
+ /// let mut mutex = Mutex::new(7);
292
+ ///
293
+ /// assert_eq!(mutex.get_cloned().unwrap(), 7);
294
+ /// ```
295
+ #[ unstable( feature = "lock_value_accessors" , issue = "133407" ) ]
296
+ pub fn get_cloned ( & self ) -> Result < T , PoisonError < ( ) > >
297
+ where
298
+ T : Clone ,
299
+ {
300
+ match self . lock ( ) {
301
+ Ok ( guard) => Ok ( ( * guard) . clone ( ) ) ,
302
+ Err ( _) => Err ( PoisonError :: new ( ( ) ) ) ,
303
+ }
304
+ }
305
+
306
+ /// Sets the contained value.
307
+ ///
308
+ /// # Errors
309
+ ///
310
+ /// If another user of this mutex panicked while holding the mutex, then
311
+ /// this call will return an error containing the provided `value` instead.
312
+ ///
313
+ /// # Examples
314
+ ///
315
+ /// ```
316
+ /// #![feature(lock_value_accessors)]
317
+ ///
318
+ /// use std::sync::Mutex;
319
+ ///
320
+ /// let mut mutex = Mutex::new(7);
321
+ ///
322
+ /// assert_eq!(mutex.get_cloned().unwrap(), 7);
323
+ /// mutex.set(11).unwrap();
324
+ /// assert_eq!(mutex.get_cloned().unwrap(), 11);
325
+ /// ```
326
+ #[ unstable( feature = "lock_value_accessors" , issue = "133407" ) ]
327
+ pub fn set ( & self , value : T ) -> Result < ( ) , PoisonError < T > > {
328
+ if mem:: needs_drop :: < T > ( ) {
329
+ // If the contained value has non-trivial destructor, we
330
+ // call that destructor after the lock being released.
331
+ self . replace ( value) . map ( drop)
332
+ } else {
333
+ match self . lock ( ) {
334
+ Ok ( mut guard) => {
335
+ * guard = value;
336
+
337
+ Ok ( ( ) )
338
+ }
339
+ Err ( _) => Err ( PoisonError :: new ( value) ) ,
340
+ }
341
+ }
342
+ }
343
+
344
+ /// Replaces the contained value with `value`, and returns the old contained value.
345
+ ///
346
+ /// # Errors
347
+ ///
348
+ /// If another user of this mutex panicked while holding the mutex, then
349
+ /// this call will return an error containing the provided `value` instead.
350
+ ///
351
+ /// # Examples
352
+ ///
353
+ /// ```
354
+ /// #![feature(lock_value_accessors)]
355
+ ///
356
+ /// use std::sync::Mutex;
357
+ ///
358
+ /// let mut mutex = Mutex::new(7);
359
+ ///
360
+ /// assert_eq!(mutex.replace(11).unwrap(), 7);
361
+ /// assert_eq!(mutex.get_cloned().unwrap(), 11);
362
+ /// ```
363
+ #[ unstable( feature = "lock_value_accessors" , issue = "133407" ) ]
364
+ pub fn replace ( & self , value : T ) -> LockResult < T > {
365
+ match self . lock ( ) {
366
+ Ok ( mut guard) => Ok ( mem:: replace ( & mut * guard, value) ) ,
367
+ Err ( _) => Err ( PoisonError :: new ( value) ) ,
368
+ }
369
+ }
276
370
}
277
371
278
372
impl < T : ?Sized > Mutex < T > {
@@ -290,7 +384,8 @@ impl<T: ?Sized> Mutex<T> {
290
384
/// # Errors
291
385
///
292
386
/// If another user of this mutex panicked while holding the mutex, then
293
- /// this call will return an error once the mutex is acquired.
387
+ /// this call will return an error once the mutex is acquired. The acquired
388
+ /// mutex guard will be contained in the returned error.
294
389
///
295
390
/// # Panics
296
391
///
@@ -331,7 +426,8 @@ impl<T: ?Sized> Mutex<T> {
331
426
///
332
427
/// If another user of this mutex panicked while holding the mutex, then
333
428
/// this call will return the [`Poisoned`] error if the mutex would
334
- /// otherwise be acquired.
429
+ /// otherwise be acquired. An acquired lock guard will be contained
430
+ /// in the returned error.
335
431
///
336
432
/// If the mutex could not be acquired because it is already locked, then
337
433
/// this call will return the [`WouldBlock`] error.
@@ -438,7 +534,8 @@ impl<T: ?Sized> Mutex<T> {
438
534
/// # Errors
439
535
///
440
536
/// If another user of this mutex panicked while holding the mutex, then
441
- /// this call will return an error instead.
537
+ /// this call will return an error containing the the underlying data
538
+ /// instead.
442
539
///
443
540
/// # Examples
444
541
///
@@ -465,7 +562,8 @@ impl<T: ?Sized> Mutex<T> {
465
562
/// # Errors
466
563
///
467
564
/// If another user of this mutex panicked while holding the mutex, then
468
- /// this call will return an error instead.
565
+ /// this call will return an error containing a mutable reference to the
566
+ /// underlying data instead.
469
567
///
470
568
/// # Examples
471
569
///
0 commit comments