@@ -14,70 +14,110 @@ public partial class AsyncReaderWriterLockFixture
14
14
public void TestBlocking ( )
15
15
{
16
16
var l = new AsyncReaderWriterLock ( ) ;
17
- for ( var i = 0 ; i < 10 ; i ++ )
17
+ for ( var i = 0 ; i < 2 ; i ++ )
18
18
{
19
19
var readReleaser = l . ReadLock ( ) ;
20
+ Assert . That ( l . CurrentReaders , Is . EqualTo ( 1 ) ) ;
21
+
20
22
var readReleaserTask = Task . Run ( ( ) => l . ReadLock ( ) ) ;
23
+ AssertEqualValue ( ( ) => l . CurrentReaders , 2 , readReleaserTask ) ;
21
24
Assert . That ( readReleaserTask . Wait ( _delay ) , Is . True ) ;
22
25
23
26
var writeReleaserTask = Task . Run ( ( ) => l . WriteLock ( ) ) ;
27
+ AssertEqualValue ( ( ) => l . AcquiredWriteLock , true , writeReleaserTask ) ;
28
+ AssertEqualValue ( ( ) => l . Writing , false , writeReleaserTask ) ;
24
29
Assert . That ( writeReleaserTask . Wait ( _delay ) , Is . False ) ;
25
30
26
31
readReleaser . Dispose ( ) ;
32
+ Assert . That ( l . CurrentReaders , Is . EqualTo ( 1 ) ) ;
27
33
Assert . That ( writeReleaserTask . Wait ( _delay ) , Is . False ) ;
28
34
29
35
readReleaserTask . Result . Dispose ( ) ;
36
+ Assert . That ( l . CurrentReaders , Is . EqualTo ( 0 ) ) ;
37
+ AssertEqualValue ( ( ) => l . Writing , true , writeReleaserTask ) ;
30
38
Assert . That ( writeReleaserTask . Wait ( _delay ) , Is . True ) ;
31
39
32
40
readReleaserTask = Task . Run ( ( ) => l . ReadLock ( ) ) ;
41
+ AssertEqualValue ( ( ) => l . ReadersWaiting , 1 , readReleaserTask ) ;
33
42
Assert . That ( readReleaserTask . Wait ( _delay ) , Is . False ) ;
34
43
35
44
var writeReleaserTask2 = Task . Run ( ( ) => l . WriteLock ( ) ) ;
45
+ AssertEqualValue ( ( ) => l . WritersWaiting , 1 , writeReleaserTask2 ) ;
36
46
Assert . That ( writeReleaserTask2 . Wait ( _delay ) , Is . False ) ;
37
47
38
48
writeReleaserTask . Result . Dispose ( ) ;
49
+ AssertEqualValue ( ( ) => l . WritersWaiting , 0 , writeReleaserTask2 ) ;
50
+ AssertEqualValue ( ( ) => l . Writing , true , writeReleaserTask2 ) ;
39
51
Assert . That ( readReleaserTask . Wait ( _delay ) , Is . False ) ;
40
52
Assert . That ( writeReleaserTask2 . Wait ( _delay ) , Is . True ) ;
41
53
42
54
writeReleaserTask2 . Result . Dispose ( ) ;
55
+ AssertEqualValue ( ( ) => l . Writing , false , writeReleaserTask2 ) ;
56
+ AssertEqualValue ( ( ) => l . ReadersWaiting , 0 , readReleaserTask ) ;
57
+ AssertEqualValue ( ( ) => l . CurrentReaders , 1 , readReleaserTask ) ;
43
58
Assert . That ( readReleaserTask . Wait ( _delay ) , Is . True ) ;
59
+
44
60
readReleaserTask . Result . Dispose ( ) ;
61
+ Assert . That ( l . ReadersWaiting , Is . EqualTo ( 0 ) ) ;
62
+ Assert . That ( l . WritersWaiting , Is . EqualTo ( 0 ) ) ;
63
+ Assert . That ( l . CurrentReaders , Is . EqualTo ( 0 ) ) ;
64
+ Assert . That ( l . Writing , Is . False ) ;
45
65
}
46
66
}
47
67
48
68
[ Test ]
49
69
public void TestBlockingAsync ( )
50
70
{
51
71
var l = new AsyncReaderWriterLock ( ) ;
52
- for ( var i = 0 ; i < 10 ; i ++ )
72
+ for ( var i = 0 ; i < 2 ; i ++ )
53
73
{
54
74
var readReleaserTask = l . ReadLockAsync ( ) ;
55
- var readReleaserTask2 = l . ReadLockAsync ( ) ;
75
+ AssertEqualValue ( ( ) => l . CurrentReaders , 1 , readReleaserTask ) ;
56
76
Assert . That ( readReleaserTask . Wait ( _delay ) , Is . True ) ;
77
+
78
+ var readReleaserTask2 = l . ReadLockAsync ( ) ;
79
+ AssertEqualValue ( ( ) => l . CurrentReaders , 2 , readReleaserTask2 ) ;
57
80
Assert . That ( readReleaserTask2 . Wait ( _delay ) , Is . True ) ;
58
81
59
82
var writeReleaserTask = l . WriteLockAsync ( ) ;
83
+ AssertEqualValue ( ( ) => l . AcquiredWriteLock , true , writeReleaserTask ) ;
84
+ AssertEqualValue ( ( ) => l . Writing , false , writeReleaserTask ) ;
60
85
Assert . That ( writeReleaserTask . Wait ( _delay ) , Is . False ) ;
61
86
62
87
readReleaserTask . Result . Dispose ( ) ;
88
+ Assert . That ( l . CurrentReaders , Is . EqualTo ( 1 ) ) ;
63
89
Assert . That ( writeReleaserTask . Wait ( _delay ) , Is . False ) ;
64
90
65
91
readReleaserTask2 . Result . Dispose ( ) ;
92
+ Assert . That ( l . CurrentReaders , Is . EqualTo ( 0 ) ) ;
93
+ AssertEqualValue ( ( ) => l . Writing , true , writeReleaserTask ) ;
66
94
Assert . That ( writeReleaserTask . Wait ( _delay ) , Is . True ) ;
67
95
68
96
readReleaserTask = l . ReadLockAsync ( ) ;
97
+ AssertEqualValue ( ( ) => l . ReadersWaiting , 1 , readReleaserTask ) ;
69
98
Assert . That ( readReleaserTask . Wait ( _delay ) , Is . False ) ;
70
99
71
100
var writeReleaserTask2 = l . WriteLockAsync ( ) ;
101
+ AssertEqualValue ( ( ) => l . WritersWaiting , 1 , writeReleaserTask2 ) ;
72
102
Assert . That ( writeReleaserTask2 . Wait ( _delay ) , Is . False ) ;
73
103
74
104
writeReleaserTask . Result . Dispose ( ) ;
105
+ AssertEqualValue ( ( ) => l . WritersWaiting , 0 , writeReleaserTask2 ) ;
106
+ AssertEqualValue ( ( ) => l . Writing , true , writeReleaserTask2 ) ;
75
107
Assert . That ( readReleaserTask . Wait ( _delay ) , Is . False ) ;
76
108
Assert . That ( writeReleaserTask2 . Wait ( _delay ) , Is . True ) ;
77
109
78
110
writeReleaserTask2 . Result . Dispose ( ) ;
111
+ AssertEqualValue ( ( ) => l . Writing , false , writeReleaserTask2 ) ;
112
+ AssertEqualValue ( ( ) => l . ReadersWaiting , 0 , readReleaserTask ) ;
113
+ AssertEqualValue ( ( ) => l . CurrentReaders , 1 , readReleaserTask ) ;
79
114
Assert . That ( readReleaserTask . Wait ( _delay ) , Is . True ) ;
115
+
80
116
readReleaserTask . Result . Dispose ( ) ;
117
+ Assert . That ( l . ReadersWaiting , Is . EqualTo ( 0 ) ) ;
118
+ Assert . That ( l . WritersWaiting , Is . EqualTo ( 0 ) ) ;
119
+ Assert . That ( l . CurrentReaders , Is . EqualTo ( 0 ) ) ;
120
+ Assert . That ( l . Writing , Is . False ) ;
81
121
}
82
122
}
83
123
@@ -109,27 +149,43 @@ public void TestMixingSyncAndAsync()
109
149
{
110
150
var l = new AsyncReaderWriterLock ( ) ;
111
151
var readReleaser = l . ReadLock ( ) ;
152
+ Assert . That ( l . CurrentReaders , Is . EqualTo ( 1 ) ) ;
153
+
112
154
var readReleaserTask = l . ReadLockAsync ( ) ;
155
+ AssertEqualValue ( ( ) => l . CurrentReaders , 2 , readReleaserTask ) ;
113
156
Assert . That ( readReleaserTask . Wait ( _delay ) , Is . True ) ;
114
157
115
158
readReleaser . Dispose ( ) ;
159
+ Assert . That ( l . CurrentReaders , Is . EqualTo ( 1 ) ) ;
160
+
116
161
readReleaserTask . Result . Dispose ( ) ;
162
+ Assert . That ( l . CurrentReaders , Is . EqualTo ( 0 ) ) ;
117
163
118
164
var writeReleaser = l . WriteLock ( ) ;
165
+ Assert . That ( l . AcquiredWriteLock , Is . True ) ;
166
+
119
167
var writeReleaserTask = l . WriteLockAsync ( ) ;
168
+ AssertEqualValue ( ( ) => l . WritersWaiting , 1 , writeReleaserTask ) ;
120
169
Assert . That ( writeReleaserTask . Wait ( _delay ) , Is . False ) ;
121
170
122
171
readReleaserTask = Task . Run ( ( ) => l . ReadLock ( ) ) ;
123
- var readReleaserTask2 = l . ReadLockAsync ( ) ;
172
+ AssertEqualValue ( ( ) => l . ReadersWaiting , 1 , readReleaserTask ) ;
124
173
Assert . That ( readReleaserTask . Wait ( _delay ) , Is . False ) ;
174
+
175
+ var readReleaserTask2 = l . ReadLockAsync ( ) ;
176
+ AssertEqualValue ( ( ) => l . ReadersWaiting , 2 , readReleaserTask2 ) ;
125
177
Assert . That ( readReleaserTask2 . Wait ( _delay ) , Is . False ) ;
126
178
127
179
writeReleaser . Dispose ( ) ;
180
+ AssertEqualValue ( ( ) => l . WritersWaiting , 0 , writeReleaserTask ) ;
181
+ AssertEqualValue ( ( ) => l . Writing , true , writeReleaserTask ) ;
128
182
Assert . That ( writeReleaserTask . Wait ( _delay ) , Is . True ) ;
129
183
Assert . That ( readReleaserTask . Wait ( _delay ) , Is . False ) ;
130
184
Assert . That ( readReleaserTask2 . Wait ( _delay ) , Is . False ) ;
131
185
132
186
writeReleaserTask . Result . Dispose ( ) ;
187
+ AssertEqualValue ( ( ) => l . CurrentReaders , 2 , readReleaserTask ) ;
188
+ AssertEqualValue ( ( ) => l . ReadersWaiting , 0 , readReleaserTask2 ) ;
133
189
Assert . That ( readReleaserTask . Wait ( _delay ) , Is . True ) ;
134
190
Assert . That ( readReleaserTask2 . Wait ( _delay ) , Is . True ) ;
135
191
}
@@ -138,17 +194,26 @@ public void TestMixingSyncAndAsync()
138
194
public void TestWritePriorityOverReadAsync ( )
139
195
{
140
196
var l = new AsyncReaderWriterLock ( ) ;
141
- for ( var i = 0 ; i < 10 ; i ++ )
197
+ for ( var i = 0 ; i < 2 ; i ++ )
142
198
{
143
199
var writeReleaser = l . WriteLock ( ) ;
200
+ Assert . That ( l . AcquiredWriteLock , Is . True ) ;
201
+
144
202
var readReleaserTask = l . ReadLockAsync ( ) ;
203
+ AssertEqualValue ( ( ) => l . ReadersWaiting , 1 , readReleaserTask ) ;
204
+
145
205
var writeReleaserTask = l . WriteLockAsync ( ) ;
206
+ AssertEqualValue ( ( ) => l . WritersWaiting , 1 , writeReleaserTask ) ;
146
207
147
208
writeReleaser . Dispose ( ) ;
209
+ AssertEqualValue ( ( ) => l . WritersWaiting , 0 , writeReleaserTask ) ;
210
+ AssertEqualValue ( ( ) => l . ReadersWaiting , 1 , readReleaserTask ) ;
148
211
Assert . That ( writeReleaserTask . Wait ( _delay ) , Is . True ) ;
149
212
150
213
writeReleaserTask . Result . Dispose ( ) ;
214
+ AssertEqualValue ( ( ) => l . ReadersWaiting , 0 , readReleaserTask ) ;
151
215
Assert . That ( readReleaserTask . Wait ( _delay ) , Is . True ) ;
216
+
152
217
readReleaserTask . Result . Dispose ( ) ;
153
218
}
154
219
}
@@ -158,25 +223,34 @@ public void TestPartialReleasingReadLockAsync()
158
223
{
159
224
var l = new AsyncReaderWriterLock ( ) ;
160
225
var readReleaserTask = l . ReadLockAsync ( ) ;
161
- var readReleaserTask2 = l . ReadLockAsync ( ) ;
226
+ AssertEqualValue ( ( ) => l . CurrentReaders , 1 , readReleaserTask ) ;
162
227
Assert . That ( readReleaserTask . Wait ( _delay ) , Is . True ) ;
228
+
229
+ var readReleaserTask2 = l . ReadLockAsync ( ) ;
230
+ AssertEqualValue ( ( ) => l . CurrentReaders , 2 , readReleaserTask ) ;
163
231
Assert . That ( readReleaserTask2 . Wait ( _delay ) , Is . True ) ;
164
232
165
233
var writeReleaserTask = l . WriteLockAsync ( ) ;
234
+ AssertEqualValue ( ( ) => l . AcquiredWriteLock , true , writeReleaserTask ) ;
235
+ AssertEqualValue ( ( ) => l . Writing , false , writeReleaserTask ) ;
166
236
Assert . That ( writeReleaserTask . Wait ( _delay ) , Is . False ) ;
167
237
168
238
var readReleaserTask3 = l . ReadLockAsync ( ) ;
239
+ AssertEqualValue ( ( ) => l . ReadersWaiting , 1 , readReleaserTask3 ) ;
169
240
Assert . That ( readReleaserTask3 . Wait ( _delay ) , Is . False ) ;
170
241
171
242
readReleaserTask . Result . Dispose ( ) ;
172
243
Assert . That ( writeReleaserTask . Wait ( _delay ) , Is . False ) ;
173
244
Assert . That ( readReleaserTask3 . Wait ( _delay ) , Is . False ) ;
174
245
175
246
readReleaserTask2 . Result . Dispose ( ) ;
247
+ AssertEqualValue ( ( ) => l . Writing , true , writeReleaserTask ) ;
248
+ AssertEqualValue ( ( ) => l . ReadersWaiting , 1 , readReleaserTask3 ) ;
176
249
Assert . That ( writeReleaserTask . Wait ( _delay ) , Is . True ) ;
177
250
Assert . That ( readReleaserTask3 . Wait ( _delay ) , Is . False ) ;
178
251
179
252
writeReleaserTask . Result . Dispose ( ) ;
253
+ AssertEqualValue ( ( ) => l . ReadersWaiting , 0 , readReleaserTask3 ) ;
180
254
Assert . That ( readReleaserTask3 . Wait ( _delay ) , Is . True ) ;
181
255
}
182
256
@@ -303,5 +377,22 @@ async Task AsyncLock(Random random, CancellationToken cancellationToken)
303
377
}
304
378
}
305
379
}
380
+
381
+ private static void AssertEqualValue < T > ( Func < T > getValueFunc , T value , Task task , int waitDelay = 500 )
382
+ {
383
+ var currentTime = 0 ;
384
+ const int step = 5 ;
385
+ while ( currentTime < waitDelay )
386
+ {
387
+ task . Wait ( step ) ;
388
+ currentTime += step ;
389
+ if ( getValueFunc ( ) . Equals ( value ) )
390
+ {
391
+ return ;
392
+ }
393
+ }
394
+
395
+ Assert . That ( getValueFunc ( ) , Is . EqualTo ( value ) ) ;
396
+ }
306
397
}
307
398
}
0 commit comments