11use crate :: sync:: atomic:: { AtomicUsize , Ordering } ;
22use crate :: sync:: mpsc:: channel;
3- use crate :: sync:: { Arc , RwLock , RwLockReadGuard , TryLockError } ;
3+ use crate :: sync:: {
4+ Arc , MappedRwLockReadGuard , MappedRwLockWriteGuard , RwLock , RwLockReadGuard , RwLockWriteGuard ,
5+ TryLockError ,
6+ } ;
47use crate :: thread;
58use rand:: Rng ;
69
@@ -55,6 +58,19 @@ fn test_rw_arc_poison_wr() {
5558 assert ! ( arc. read( ) . is_err( ) ) ;
5659}
5760
61+ #[ test]
62+ fn test_rw_arc_poison_mapped_w_r ( ) {
63+ let arc = Arc :: new ( RwLock :: new ( 1 ) ) ;
64+ let arc2 = arc. clone ( ) ;
65+ let _: Result < ( ) , _ > = thread:: spawn ( move || {
66+ let lock = arc2. write ( ) . unwrap ( ) ;
67+ let _lock = RwLockWriteGuard :: map ( lock, |val| val) ;
68+ panic ! ( ) ;
69+ } )
70+ . join ( ) ;
71+ assert ! ( arc. read( ) . is_err( ) ) ;
72+ }
73+
5874#[ test]
5975fn test_rw_arc_poison_ww ( ) {
6076 let arc = Arc :: new ( RwLock :: new ( 1 ) ) ;
@@ -69,6 +85,20 @@ fn test_rw_arc_poison_ww() {
6985 assert ! ( arc. is_poisoned( ) ) ;
7086}
7187
88+ #[ test]
89+ fn test_rw_arc_poison_mapped_w_w ( ) {
90+ let arc = Arc :: new ( RwLock :: new ( 1 ) ) ;
91+ let arc2 = arc. clone ( ) ;
92+ let _: Result < ( ) , _ > = thread:: spawn ( move || {
93+ let lock = arc2. write ( ) . unwrap ( ) ;
94+ let _lock = RwLockWriteGuard :: map ( lock, |val| val) ;
95+ panic ! ( ) ;
96+ } )
97+ . join ( ) ;
98+ assert ! ( arc. write( ) . is_err( ) ) ;
99+ assert ! ( arc. is_poisoned( ) ) ;
100+ }
101+
72102#[ test]
73103fn test_rw_arc_no_poison_rr ( ) {
74104 let arc = Arc :: new ( RwLock :: new ( 1 ) ) ;
@@ -81,6 +111,21 @@ fn test_rw_arc_no_poison_rr() {
81111 let lock = arc. read ( ) . unwrap ( ) ;
82112 assert_eq ! ( * lock, 1 ) ;
83113}
114+
115+ #[ test]
116+ fn test_rw_arc_no_poison_mapped_r_r ( ) {
117+ let arc = Arc :: new ( RwLock :: new ( 1 ) ) ;
118+ let arc2 = arc. clone ( ) ;
119+ let _: Result < ( ) , _ > = thread:: spawn ( move || {
120+ let lock = arc2. read ( ) . unwrap ( ) ;
121+ let _lock = RwLockReadGuard :: map ( lock, |val| val) ;
122+ panic ! ( ) ;
123+ } )
124+ . join ( ) ;
125+ let lock = arc. read ( ) . unwrap ( ) ;
126+ assert_eq ! ( * lock, 1 ) ;
127+ }
128+
84129#[ test]
85130fn test_rw_arc_no_poison_rw ( ) {
86131 let arc = Arc :: new ( RwLock :: new ( 1 ) ) ;
@@ -94,6 +139,20 @@ fn test_rw_arc_no_poison_rw() {
94139 assert_eq ! ( * lock, 1 ) ;
95140}
96141
142+ #[ test]
143+ fn test_rw_arc_no_poison_mapped_r_w ( ) {
144+ let arc = Arc :: new ( RwLock :: new ( 1 ) ) ;
145+ let arc2 = arc. clone ( ) ;
146+ let _: Result < ( ) , _ > = thread:: spawn ( move || {
147+ let lock = arc2. read ( ) . unwrap ( ) ;
148+ let _lock = RwLockReadGuard :: map ( lock, |val| val) ;
149+ panic ! ( ) ;
150+ } )
151+ . join ( ) ;
152+ let lock = arc. write ( ) . unwrap ( ) ;
153+ assert_eq ! ( * lock, 1 ) ;
154+ }
155+
97156#[ test]
98157fn test_rw_arc ( ) {
99158 let arc = Arc :: new ( RwLock :: new ( 0 ) ) ;
@@ -179,6 +238,16 @@ fn test_rwlock_try_write() {
179238 }
180239
181240 drop ( read_guard) ;
241+ let mapped_read_guard = RwLockReadGuard :: map ( lock. read ( ) . unwrap ( ) , |_| & ( ) ) ;
242+
243+ let write_result = lock. try_write ( ) ;
244+ match write_result {
245+ Err ( TryLockError :: WouldBlock ) => ( ) ,
246+ Ok ( _) => assert ! ( false , "try_write should not succeed while mapped_read_guard is in scope" ) ,
247+ Err ( _) => assert ! ( false , "unexpected error" ) ,
248+ }
249+
250+ drop ( mapped_read_guard) ;
182251}
183252
184253#[ test]
@@ -257,3 +326,37 @@ fn test_read_guard_covariance() {
257326 }
258327 drop ( lock) ;
259328}
329+
330+ #[ test]
331+ fn test_mapped_read_guard_covariance ( ) {
332+ fn do_stuff < ' a > ( _: MappedRwLockReadGuard < ' _ , & ' a i32 > , _: & ' a i32 ) { }
333+ let j: i32 = 5 ;
334+ let lock = RwLock :: new ( ( & j, & j) ) ;
335+ {
336+ let i = 6 ;
337+ let guard = lock. read ( ) . unwrap ( ) ;
338+ let guard = RwLockReadGuard :: map ( guard, |( val, _val) | val) ;
339+ do_stuff ( guard, & i) ;
340+ }
341+ drop ( lock) ;
342+ }
343+
344+ #[ test]
345+ fn test_mapping_mapped_guard ( ) {
346+ let arr = [ 0 ; 4 ] ;
347+ let mut lock = RwLock :: new ( arr) ;
348+ let guard = lock. write ( ) . unwrap ( ) ;
349+ let guard = RwLockWriteGuard :: map ( guard, |arr| & mut arr[ ..2 ] ) ;
350+ let mut guard = MappedRwLockWriteGuard :: map ( guard, |slice| & mut slice[ 1 ..] ) ;
351+ assert_eq ! ( guard. len( ) , 1 ) ;
352+ guard[ 0 ] = 42 ;
353+ drop ( guard) ;
354+ assert_eq ! ( * lock. get_mut( ) . unwrap( ) , [ 0 , 42 , 0 , 0 ] ) ;
355+
356+ let guard = lock. read ( ) . unwrap ( ) ;
357+ let guard = RwLockReadGuard :: map ( guard, |arr| & arr[ ..2 ] ) ;
358+ let guard = MappedRwLockReadGuard :: map ( guard, |slice| & slice[ 1 ..] ) ;
359+ assert_eq ! ( * guard, [ 42 ] ) ;
360+ drop ( guard) ;
361+ assert_eq ! ( * lock. get_mut( ) . unwrap( ) , [ 0 , 42 , 0 , 0 ] ) ;
362+ }
0 commit comments