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:: {
4
+ Arc , MappedRwLockReadGuard , MappedRwLockWriteGuard , RwLock , RwLockReadGuard , RwLockWriteGuard ,
5
+ TryLockError ,
6
+ } ;
4
7
use crate :: thread;
5
8
use rand:: Rng ;
6
9
@@ -55,6 +58,19 @@ fn test_rw_arc_poison_wr() {
55
58
assert ! ( arc. read( ) . is_err( ) ) ;
56
59
}
57
60
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
+
58
74
#[ test]
59
75
fn test_rw_arc_poison_ww ( ) {
60
76
let arc = Arc :: new ( RwLock :: new ( 1 ) ) ;
@@ -69,6 +85,20 @@ fn test_rw_arc_poison_ww() {
69
85
assert ! ( arc. is_poisoned( ) ) ;
70
86
}
71
87
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
+
72
102
#[ test]
73
103
fn test_rw_arc_no_poison_rr ( ) {
74
104
let arc = Arc :: new ( RwLock :: new ( 1 ) ) ;
@@ -81,6 +111,21 @@ fn test_rw_arc_no_poison_rr() {
81
111
let lock = arc. read ( ) . unwrap ( ) ;
82
112
assert_eq ! ( * lock, 1 ) ;
83
113
}
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
+
84
129
#[ test]
85
130
fn test_rw_arc_no_poison_rw ( ) {
86
131
let arc = Arc :: new ( RwLock :: new ( 1 ) ) ;
@@ -94,6 +139,20 @@ fn test_rw_arc_no_poison_rw() {
94
139
assert_eq ! ( * lock, 1 ) ;
95
140
}
96
141
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
+
97
156
#[ test]
98
157
fn test_rw_arc ( ) {
99
158
let arc = Arc :: new ( RwLock :: new ( 0 ) ) ;
@@ -179,6 +238,16 @@ fn test_rwlock_try_write() {
179
238
}
180
239
181
240
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) ;
182
251
}
183
252
184
253
#[ test]
@@ -257,3 +326,37 @@ fn test_read_guard_covariance() {
257
326
}
258
327
drop ( lock) ;
259
328
}
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