1
1
use crate :: sync:: atomic:: { AtomicUsize , Ordering } ;
2
2
use crate :: sync:: mpsc:: channel;
3
- use crate :: sync:: { Arc , RwLock , RwLockReadGuard , TryLockError } ;
3
+ use crate :: sync:: { Arc , RwLock , RwLockReadGuard , RwLockWriteGuard , MappedRwLockReadGuard , MappedRwLockWriteGuard , TryLockError } ;
4
4
use crate :: thread;
5
5
use rand:: Rng ;
6
6
@@ -55,6 +55,19 @@ fn test_rw_arc_poison_wr() {
55
55
assert ! ( arc. read( ) . is_err( ) ) ;
56
56
}
57
57
58
+ #[ test]
59
+ fn test_rw_arc_poison_mapped_w_r ( ) {
60
+ let arc = Arc :: new ( RwLock :: new ( 1 ) ) ;
61
+ let arc2 = arc. clone ( ) ;
62
+ let _: Result < ( ) , _ > = thread:: spawn ( move || {
63
+ let lock = arc2. write ( ) . unwrap ( ) ;
64
+ let _lock = RwLockWriteGuard :: map ( lock, |val| val) ;
65
+ panic ! ( ) ;
66
+ } )
67
+ . join ( ) ;
68
+ assert ! ( arc. read( ) . is_err( ) ) ;
69
+ }
70
+
58
71
#[ test]
59
72
fn test_rw_arc_poison_ww ( ) {
60
73
let arc = Arc :: new ( RwLock :: new ( 1 ) ) ;
@@ -69,6 +82,20 @@ fn test_rw_arc_poison_ww() {
69
82
assert ! ( arc. is_poisoned( ) ) ;
70
83
}
71
84
85
+ #[ test]
86
+ fn test_rw_arc_poison_mapped_w_w ( ) {
87
+ let arc = Arc :: new ( RwLock :: new ( 1 ) ) ;
88
+ let arc2 = arc. clone ( ) ;
89
+ let _: Result < ( ) , _ > = thread:: spawn ( move || {
90
+ let lock = arc2. write ( ) . unwrap ( ) ;
91
+ let _lock = RwLockWriteGuard :: map ( lock, |val| val) ;
92
+ panic ! ( ) ;
93
+ } )
94
+ . join ( ) ;
95
+ assert ! ( arc. write( ) . is_err( ) ) ;
96
+ assert ! ( arc. is_poisoned( ) ) ;
97
+ }
98
+
72
99
#[ test]
73
100
fn test_rw_arc_no_poison_rr ( ) {
74
101
let arc = Arc :: new ( RwLock :: new ( 1 ) ) ;
@@ -81,6 +108,21 @@ fn test_rw_arc_no_poison_rr() {
81
108
let lock = arc. read ( ) . unwrap ( ) ;
82
109
assert_eq ! ( * lock, 1 ) ;
83
110
}
111
+
112
+ #[ test]
113
+ fn test_rw_arc_no_poison_mapped_r_r ( ) {
114
+ let arc = Arc :: new ( RwLock :: new ( 1 ) ) ;
115
+ let arc2 = arc. clone ( ) ;
116
+ let _: Result < ( ) , _ > = thread:: spawn ( move || {
117
+ let lock = arc2. read ( ) . unwrap ( ) ;
118
+ let _lock = RwLockReadGuard :: map ( lock, |val| val) ;
119
+ panic ! ( ) ;
120
+ } )
121
+ . join ( ) ;
122
+ let lock = arc. read ( ) . unwrap ( ) ;
123
+ assert_eq ! ( * lock, 1 ) ;
124
+ }
125
+
84
126
#[ test]
85
127
fn test_rw_arc_no_poison_rw ( ) {
86
128
let arc = Arc :: new ( RwLock :: new ( 1 ) ) ;
@@ -94,6 +136,20 @@ fn test_rw_arc_no_poison_rw() {
94
136
assert_eq ! ( * lock, 1 ) ;
95
137
}
96
138
139
+ #[ test]
140
+ fn test_rw_arc_no_poison_mapped_r_w ( ) {
141
+ let arc = Arc :: new ( RwLock :: new ( 1 ) ) ;
142
+ let arc2 = arc. clone ( ) ;
143
+ let _: Result < ( ) , _ > = thread:: spawn ( move || {
144
+ let lock = arc2. read ( ) . unwrap ( ) ;
145
+ let _lock = RwLockReadGuard :: map ( lock, |val| val) ;
146
+ panic ! ( ) ;
147
+ } )
148
+ . join ( ) ;
149
+ let lock = arc. write ( ) . unwrap ( ) ;
150
+ assert_eq ! ( * lock, 1 ) ;
151
+ }
152
+
97
153
#[ test]
98
154
fn test_rw_arc ( ) {
99
155
let arc = Arc :: new ( RwLock :: new ( 0 ) ) ;
@@ -179,6 +235,16 @@ fn test_rwlock_try_write() {
179
235
}
180
236
181
237
drop ( read_guard) ;
238
+ let mapped_read_guard = RwLockReadGuard :: map ( lock. read ( ) . unwrap ( ) , |_| & ( ) ) ;
239
+
240
+ let write_result = lock. try_write ( ) ;
241
+ match write_result {
242
+ Err ( TryLockError :: WouldBlock ) => ( ) ,
243
+ Ok ( _) => assert ! ( false , "try_write should not succeed while mapped_read_guard is in scope" ) ,
244
+ Err ( _) => assert ! ( false , "unexpected error" ) ,
245
+ }
246
+
247
+ drop ( mapped_read_guard) ;
182
248
}
183
249
184
250
#[ test]
@@ -257,3 +323,37 @@ fn test_read_guard_covariance() {
257
323
}
258
324
drop ( lock) ;
259
325
}
326
+
327
+ #[ test]
328
+ fn test_mapped_read_guard_covariance ( ) {
329
+ fn do_stuff < ' a > ( _: MappedRwLockReadGuard < ' _ , & ' a i32 > , _: & ' a i32 ) { }
330
+ let j: i32 = 5 ;
331
+ let lock = RwLock :: new ( ( & j, & j) ) ;
332
+ {
333
+ let i = 6 ;
334
+ let guard = lock. read ( ) . unwrap ( ) ;
335
+ let guard = RwLockReadGuard :: map ( guard, |( val, _val) | val) ;
336
+ do_stuff ( guard, & i) ;
337
+ }
338
+ drop ( lock) ;
339
+ }
340
+
341
+ #[ test]
342
+ fn test_mapping_mapped_guard ( ) {
343
+ let arr = [ 0 ; 4 ] ;
344
+ let mut lock = RwLock :: new ( arr) ;
345
+ let guard = lock. write ( ) . unwrap ( ) ;
346
+ let guard = RwLockWriteGuard :: map ( guard, |arr| & mut arr[ ..2 ] ) ;
347
+ let mut guard = MappedRwLockWriteGuard :: map ( guard, |slice| & mut slice[ 1 ..] ) ;
348
+ assert_eq ! ( guard. len( ) , 1 ) ;
349
+ guard[ 0 ] = 42 ;
350
+ drop ( guard) ;
351
+ assert_eq ! ( * lock. get_mut( ) . unwrap( ) , [ 0 , 42 , 0 , 0 ] ) ;
352
+
353
+ let guard = lock. read ( ) . unwrap ( ) ;
354
+ let guard = RwLockReadGuard :: map ( guard, |arr| & arr[ ..2 ] ) ;
355
+ let guard = MappedRwLockReadGuard :: map ( guard, |slice| & slice[ 1 ..] ) ;
356
+ assert_eq ! ( * guard, [ 42 ] ) ;
357
+ drop ( guard) ;
358
+ assert_eq ! ( * lock. get_mut( ) . unwrap( ) , [ 0 , 42 , 0 , 0 ] ) ;
359
+ }
0 commit comments