@@ -409,6 +409,60 @@ impl<T: ?Sized> RwLock<T> {
409
409
let data = unsafe { & mut * self . data . get ( ) } ;
410
410
poison:: map_result ( self . poison . borrow ( ) , |_| data)
411
411
}
412
+
413
+ /// Call function while holding write lock
414
+ ///
415
+ /// This attempts to take the write lock, and if successful passes a mutable
416
+ /// reference to the value to the callback.
417
+ ///
418
+ /// # Panics
419
+ ///
420
+ /// This function will panic if the RwLock is poisoned. An RwLock
421
+ /// is poisoned whenever a writer panics while holding an exclusive lock.
422
+ ///
423
+ /// # Example
424
+ ///
425
+ /// ```
426
+ /// # #![feature(mutex_with)]
427
+ /// use std::sync::RwLock;
428
+ ///
429
+ /// let rw = RwLock::new(String::new());
430
+ ///
431
+ /// let prev = rw.with_write(|mut s| {
432
+ /// let prev = s.clone();
433
+ /// *s += "foo";
434
+ /// prev
435
+ /// });
436
+ /// ```
437
+ #[ unstable( feature = "mutex_with" , issue = "61974" ) ]
438
+ pub fn with_write < U , F : FnOnce ( & mut T ) -> U > ( & self , func : F ) -> U {
439
+ self . write ( ) . map ( |mut v| func ( & mut * v) ) . expect ( "RwLock poisoned" )
440
+ }
441
+
442
+ /// Call function while holding read lock
443
+ ///
444
+ /// This attempts to take the read lock, and if successful passes a
445
+ /// reference to the value to the callback.
446
+ ///
447
+ /// # Panics
448
+ ///
449
+ /// This function will panic if the RwLock is poisoned. An RwLock
450
+ /// is poisoned whenever a writer panics while holding an exclusive lock.
451
+ ///
452
+ /// # Example
453
+ ///
454
+ /// ```
455
+ /// # #![feature(mutex_with)]
456
+ /// use std::sync::RwLock;
457
+ ///
458
+ /// let rw = RwLock::new("hello world".to_string());
459
+ ///
460
+ /// let val = rw.with_read(|s| s.clone());
461
+ /// ```
462
+ #[ unstable( feature = "mutex_with" , issue = "61974" ) ]
463
+ pub fn with_read < U , F : FnOnce ( & T ) -> U > ( & self , func : F ) -> U {
464
+ self . read ( ) . map ( |v| func ( & * v) ) . expect ( "RwLock poisoned" )
465
+ }
412
466
}
413
467
414
468
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -797,4 +851,24 @@ mod tests {
797
851
Ok ( x) => panic ! ( "get_mut of poisoned RwLock is Ok: {:?}" , x) ,
798
852
}
799
853
}
854
+
855
+ #[ test]
856
+ fn test_with_read ( ) {
857
+ let m = RwLock :: new ( 10 ) ;
858
+
859
+ let v = m. with_read ( |v| * v) ;
860
+
861
+ assert_eq ! ( v, 10 ) ;
862
+ }
863
+
864
+ #[ test]
865
+ fn test_with_write ( ) {
866
+ let m = RwLock :: new ( 10 ) ;
867
+
868
+ let old = m. with_write ( |v| { let old = * v; * v += 1 ; old} ) ;
869
+ let now = m. with_read ( |v| * v) ;
870
+
871
+ assert_eq ! ( old, 10 ) ;
872
+ assert_eq ! ( now, 11 ) ;
873
+ }
800
874
}
0 commit comments