@@ -4,10 +4,10 @@ mod tests;
44use crate :: cell:: UnsafeCell ;
55use crate :: fmt;
66use crate :: marker:: PhantomData ;
7- use crate :: mem:: ManuallyDrop ;
7+ use crate :: mem:: { self , ManuallyDrop } ;
88use crate :: ops:: { Deref , DerefMut } ;
99use crate :: ptr:: NonNull ;
10- use crate :: sync:: { LockResult , TryLockError , TryLockResult , poison} ;
10+ use crate :: sync:: { LockResult , PoisonError , TryLockError , TryLockResult , poison} ;
1111use crate :: sys:: sync as sys;
1212
1313/// A mutual exclusion primitive useful for protecting shared data
@@ -273,6 +273,100 @@ impl<T> Mutex<T> {
273273 pub const fn new ( t : T ) -> Mutex < T > {
274274 Mutex { inner : sys:: Mutex :: new ( ) , poison : poison:: Flag :: new ( ) , data : UnsafeCell :: new ( t) }
275275 }
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+ }
276370}
277371
278372impl < T : ?Sized > Mutex < T > {
@@ -290,7 +384,8 @@ impl<T: ?Sized> Mutex<T> {
290384 /// # Errors
291385 ///
292386 /// 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.
294389 ///
295390 /// # Panics
296391 ///
@@ -331,7 +426,8 @@ impl<T: ?Sized> Mutex<T> {
331426 ///
332427 /// If another user of this mutex panicked while holding the mutex, then
333428 /// 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.
335431 ///
336432 /// If the mutex could not be acquired because it is already locked, then
337433 /// this call will return the [`WouldBlock`] error.
@@ -438,7 +534,8 @@ impl<T: ?Sized> Mutex<T> {
438534 /// # Errors
439535 ///
440536 /// 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.
442539 ///
443540 /// # Examples
444541 ///
@@ -465,7 +562,8 @@ impl<T: ?Sized> Mutex<T> {
465562 /// # Errors
466563 ///
467564 /// 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.
469567 ///
470568 /// # Examples
471569 ///
0 commit comments