2 // ReaderWriterLockTest.cs - NUnit Test Cases for System.Threading.ReaderWriterLock
5 // Lluis Sanchez Gual (lluis@ximian.com)
7 // (C) 2004 Novell, Inc (http://www.novell.com)
10 using NUnit.Framework;
12 using System.Threading;
14 namespace MonoTests.System.Threading
17 public class ReaderWriterLockTest
19 ReaderWriterLock rwlock;
23 public ThreadStart SecondaryThread;
24 public Exception ResultException;
25 public Thread RunningThread;
41 RunningThread.Join (5000);
42 if (ResultException != null) throw ResultException;
46 void RunThread (ThreadStart ts)
48 ThreadRunner tr = StartThread (ts);
52 ThreadRunner StartThread (ThreadStart ts)
54 ThreadRunner tr = new ThreadRunner();
55 tr.SecondaryThread = ts;
56 Thread t = new Thread (new ThreadStart (tr.Run));
63 public void TestIsReaderLockHeld ()
65 rwlock = new ReaderWriterLock ();
66 Assert.IsTrue (!rwlock.IsReaderLockHeld, "#1");
67 rwlock.AcquireReaderLock (500);
68 Assert.IsTrue (rwlock.IsReaderLockHeld, "#1");
69 RunThread (new ThreadStart (IsReaderLockHeld_2));
70 rwlock.ReleaseReaderLock ();
73 private void IsReaderLockHeld_2 ()
75 Assert.IsTrue (!rwlock.IsReaderLockHeld);
79 public void TestIsWriterLockHeld ()
81 rwlock = new ReaderWriterLock ();
82 Assert.IsTrue (!rwlock.IsWriterLockHeld, "#1");
83 rwlock.AcquireWriterLock (500);
84 Assert.IsTrue (rwlock.IsWriterLockHeld, "#2");
85 RunThread (new ThreadStart (IsWriterLockHeld_2));
86 rwlock.ReleaseWriterLock ();
89 private void IsWriterLockHeld_2 ()
91 Assert.IsTrue (!rwlock.IsWriterLockHeld);
95 public void TestAcquireLocks ()
97 rwlock = new ReaderWriterLock ();
98 rwlock.AcquireReaderLock (500);
99 rwlock.AcquireReaderLock (500);
100 rwlock.ReleaseReaderLock ();
101 Assert.IsTrue (rwlock.IsReaderLockHeld, "#1");
102 RunThread (new ThreadStart (AcquireLock_readerWorks));
103 Assert.IsTrue (rwlock.IsReaderLockHeld);
105 RunThread (new ThreadStart (AcquireLock_writerFails));
106 rwlock.ReleaseReaderLock ();
107 Assert.IsTrue (!rwlock.IsReaderLockHeld);
109 RunThread (new ThreadStart (AcquireLock_writerWorks));
111 rwlock.AcquireWriterLock (200);
112 RunThread (new ThreadStart (AcquireLock_writerFails));
113 RunThread (new ThreadStart (AcquireLock_readerFails));
114 rwlock.ReleaseWriterLock ();
117 void AcquireLock_readerWorks ()
119 rwlock.AcquireReaderLock (200);
120 rwlock.AcquireReaderLock (200);
121 rwlock.ReleaseReaderLock ();
122 Assert.IsTrue (rwlock.IsReaderLockHeld);
123 rwlock.ReleaseReaderLock ();
124 Assert.IsTrue (!rwlock.IsReaderLockHeld);
127 void AcquireLock_writerFails ()
131 rwlock.AcquireWriterLock (200);
132 rwlock.ReleaseWriterLock ();
133 throw new Exception ("Should not get writer lock");
140 void AcquireLock_writerWorks ()
142 rwlock.AcquireWriterLock (200);
143 rwlock.ReleaseWriterLock ();
146 void AcquireLock_readerFails ()
150 rwlock.AcquireReaderLock (200);
151 rwlock.ReleaseReaderLock ();
152 throw new Exception ("Should not get reader lock");
160 public void TestReleaseRestoreReaderLock ()
162 rwlock = new ReaderWriterLock ();
163 rwlock.AcquireReaderLock (500);
164 rwlock.AcquireReaderLock (500);
165 Assert.IsTrue (rwlock.IsReaderLockHeld);
167 LockCookie co = rwlock.ReleaseLock ();
168 RunThread (new ThreadStart (AcquireLock_writerWorks));
170 rwlock.RestoreLock (ref co);
171 RunThread (new ThreadStart (AcquireLock_writerFails));
173 rwlock.ReleaseReaderLock ();
174 Assert.IsTrue (rwlock.IsReaderLockHeld);
175 rwlock.ReleaseReaderLock ();
176 Assert.IsTrue (!rwlock.IsReaderLockHeld);
180 public void TestReleaseRestoreWriterLock ()
182 rwlock = new ReaderWriterLock ();
183 rwlock.AcquireWriterLock (500);
184 rwlock.AcquireWriterLock (500);
185 Assert.IsTrue (rwlock.IsWriterLockHeld);
187 LockCookie co = rwlock.ReleaseLock ();
188 RunThread (new ThreadStart (AcquireLock_readerWorks));
190 rwlock.RestoreLock (ref co);
191 RunThread (new ThreadStart (AcquireLock_readerFails));
193 rwlock.ReleaseWriterLock ();
194 Assert.IsTrue (rwlock.IsWriterLockHeld);
195 rwlock.ReleaseWriterLock ();
196 Assert.IsTrue (!rwlock.IsWriterLockHeld);
200 public void TestUpgradeDowngradeLock ()
202 rwlock = new ReaderWriterLock ();
203 rwlock.AcquireReaderLock (200);
204 rwlock.AcquireReaderLock (200);
206 LockCookie co = rwlock.UpgradeToWriterLock (200);
207 Assert.IsTrue (!rwlock.IsReaderLockHeld);
208 Assert.IsTrue (rwlock.IsWriterLockHeld);
209 RunThread (new ThreadStart (AcquireLock_writerFails));
211 rwlock.DowngradeFromWriterLock (ref co);
212 Assert.IsTrue (rwlock.IsReaderLockHeld);
213 Assert.IsTrue (!rwlock.IsWriterLockHeld);
214 RunThread (new ThreadStart (AcquireLock_readerWorks));
216 rwlock.ReleaseReaderLock ();
217 Assert.IsTrue (rwlock.IsReaderLockHeld);
218 rwlock.ReleaseReaderLock ();
219 Assert.IsTrue (!rwlock.IsReaderLockHeld);
223 public void TestReaderInsideWriter ()
225 // Reader acquires and releases work like the writer equivalent
227 rwlock = new ReaderWriterLock ();
228 rwlock.AcquireWriterLock (-1);
229 rwlock.AcquireReaderLock (-1);
230 Assert.IsTrue (!rwlock.IsReaderLockHeld);
231 Assert.IsTrue (rwlock.IsWriterLockHeld);
232 rwlock.AcquireReaderLock (-1);
233 Assert.IsTrue (!rwlock.IsReaderLockHeld);
234 Assert.IsTrue (rwlock.IsWriterLockHeld);
235 rwlock.ReleaseWriterLock ();
236 Assert.IsTrue (!rwlock.IsReaderLockHeld);
237 Assert.IsTrue (rwlock.IsWriterLockHeld);
238 rwlock.ReleaseReaderLock ();
239 Assert.IsTrue (!rwlock.IsReaderLockHeld);
240 Assert.IsTrue (rwlock.IsWriterLockHeld);
241 rwlock.ReleaseReaderLock ();
242 Assert.IsTrue (!rwlock.IsReaderLockHeld);
243 Assert.IsTrue (!rwlock.IsWriterLockHeld);
247 public void TestReaderMustWaitWriter ()
249 // A thread cannot get the reader lock if there are other threads
250 // waiting for the writer lock.
252 rwlock = new ReaderWriterLock ();
253 rwlock.AcquireWriterLock (200);
255 ThreadRunner tr = StartThread (new ThreadStart (ReaderMustWaitWriter_2));
258 RunThread (new ThreadStart (AcquireLock_readerFails));
260 rwlock.ReleaseReaderLock ();
264 void ReaderMustWaitWriter_2 ()
266 rwlock.AcquireWriterLock (2000);
267 rwlock.ReleaseWriterLock ();
271 public void TestBug_55911 ()
273 rwlock = new ReaderWriterLock ();
275 rwlock.AcquireReaderLock (Timeout.Infinite);
277 LockCookie lc = rwlock.UpgradeToWriterLock (Timeout.Infinite);
279 finally { rwlock.ReleaseReaderLock(); }
281 rwlock.AcquireReaderLock (Timeout.Infinite);
283 LockCookie lc = rwlock.UpgradeToWriterLock (Timeout.Infinite);
285 finally { rwlock.ReleaseReaderLock(); }
289 public void TestBug_55909 ()
291 rwlock = new ReaderWriterLock ();
292 ThreadRunner tr = StartThread (new ThreadStart(Bug_55909_Thread2));
294 rwlock.AcquireReaderLock (Timeout.Infinite);
296 LockCookie lc = rwlock.UpgradeToWriterLock (Timeout.Infinite);
299 finally { rwlock.ReleaseReaderLock(); }
304 public void Bug_55909_Thread2 ()
306 rwlock.AcquireReaderLock(Timeout.Infinite);
309 LockCookie lc = rwlock.UpgradeToWriterLock (Timeout.Infinite);
312 finally { rwlock.ReleaseReaderLock(); }
316 public void TestBug_55909_bis ()
318 rwlock = new ReaderWriterLock ();
319 ThreadRunner tr1 = StartThread (new ThreadStart(Bug_55909_bis_ReaderWriter));
321 ThreadRunner tr2 = StartThread (new ThreadStart(Bug_55909_bis_Reader));
323 ThreadRunner tr3 = StartThread (new ThreadStart(Bug_55909_bis_Writer));
325 ThreadRunner tr4 = StartThread (new ThreadStart(Bug_55909_bis_Reader));
332 void Bug_55909_bis_Reader ()
334 rwlock.AcquireReaderLock(-1);
336 rwlock.ReleaseReaderLock();
339 void Bug_55909_bis_ReaderWriter ()
341 rwlock.AcquireReaderLock(-1);
342 LockCookie lc = rwlock.UpgradeToWriterLock(-1);
344 rwlock.DowngradeFromWriterLock(ref lc);
345 rwlock.ReleaseReaderLock();
348 void Bug_55909_bis_Writer ()
350 rwlock.AcquireWriterLock(-1);
351 rwlock.ReleaseWriterLock();
356 public void TestBug_475124 ()
360 rwlock = new ReaderWriterLock ();
362 Assert.IsFalse (rwlock.IsReaderLockHeld, "A1");
363 Assert.IsFalse (rwlock.IsWriterLockHeld, "A2");
365 rwlock.AcquireReaderLock (Timeout.Infinite);
367 Assert.IsTrue (rwlock.IsReaderLockHeld, "B1");
368 Assert.IsFalse (rwlock.IsWriterLockHeld, "B2");
370 lc1 = rwlock.UpgradeToWriterLock (Timeout.Infinite);
372 Assert.IsFalse (rwlock.IsReaderLockHeld, "C1");
373 Assert.IsTrue (rwlock.IsWriterLockHeld, "C2");
375 rwlock.AcquireReaderLock (Timeout.Infinite);
377 Assert.IsFalse (rwlock.IsReaderLockHeld, "D1");
378 Assert.IsTrue (rwlock.IsWriterLockHeld, "D2");
380 lc2 = rwlock.UpgradeToWriterLock (Timeout.Infinite);
382 Assert.IsFalse (rwlock.IsReaderLockHeld, "E1");
383 Assert.IsTrue (rwlock.IsWriterLockHeld, "E2");
385 rwlock.DowngradeFromWriterLock (ref lc2);
387 Assert.IsFalse (rwlock.IsReaderLockHeld, "F1");
388 Assert.IsTrue (rwlock.IsWriterLockHeld, "F2");
390 rwlock.ReleaseReaderLock ();
392 Assert.IsFalse (rwlock.IsReaderLockHeld, "G1");
393 Assert.IsTrue (rwlock.IsWriterLockHeld, "G2");
395 rwlock.DowngradeFromWriterLock (ref lc1);
397 Assert.IsTrue (rwlock.IsReaderLockHeld, "H1");
398 Assert.IsFalse (rwlock.IsWriterLockHeld, "H2");
400 rwlock.ReleaseReaderLock ();
402 Assert.IsFalse (rwlock.IsReaderLockHeld, "I1");
403 Assert.IsFalse (rwlock.IsWriterLockHeld, "I2");
406 // this tests how downgrade works when multiple writer locks
407 // are acquired - as long as the LockCookie referes to an
408 // upgrade where there was already a writer lock, downgrade
409 // behaves like a non-blocking ReleaseWriterLock
411 public void DowngradeTest ()
413 LockCookie lc1, lc2, lc3, lc4;
415 rwlock = new ReaderWriterLock ();
417 rwlock.AcquireReaderLock (Timeout.Infinite);
418 lc1 = rwlock.UpgradeToWriterLock (Timeout.Infinite);
419 rwlock.AcquireReaderLock (Timeout.Infinite);
420 lc2 = rwlock.UpgradeToWriterLock (Timeout.Infinite);
421 rwlock.AcquireReaderLock (Timeout.Infinite);
422 lc3 = rwlock.UpgradeToWriterLock (Timeout.Infinite);
423 rwlock.AcquireReaderLock (Timeout.Infinite);
424 lc4 = rwlock.UpgradeToWriterLock (Timeout.Infinite);
426 rwlock.DowngradeFromWriterLock (ref lc2);
428 Assert.IsFalse (rwlock.IsReaderLockHeld, "A1");
429 Assert.IsTrue (rwlock.IsWriterLockHeld, "A2");
431 rwlock.ReleaseReaderLock ();
433 Assert.IsFalse (rwlock.IsReaderLockHeld, "B1");
434 Assert.IsTrue (rwlock.IsWriterLockHeld, "B2");
436 rwlock.DowngradeFromWriterLock (ref lc4);
438 Assert.IsFalse (rwlock.IsReaderLockHeld, "C1");
439 Assert.IsTrue (rwlock.IsWriterLockHeld, "C2");
441 rwlock.ReleaseReaderLock ();
443 Assert.IsFalse (rwlock.IsReaderLockHeld, "D1");
444 Assert.IsTrue (rwlock.IsWriterLockHeld, "D2");
446 rwlock.DowngradeFromWriterLock (ref lc3);
448 Assert.IsFalse (rwlock.IsReaderLockHeld, "E1");
449 Assert.IsTrue (rwlock.IsWriterLockHeld, "E2");
451 rwlock.ReleaseReaderLock ();
453 Assert.IsFalse (rwlock.IsReaderLockHeld, "F1");
454 Assert.IsTrue (rwlock.IsWriterLockHeld, "F2");
456 rwlock.DowngradeFromWriterLock (ref lc1);
458 Assert.IsTrue (rwlock.IsReaderLockHeld, "G1");
459 Assert.IsFalse (rwlock.IsWriterLockHeld, "G2");
461 rwlock.ReleaseReaderLock ();
463 Assert.IsFalse (rwlock.IsReaderLockHeld, "H1");
464 Assert.IsFalse (rwlock.IsWriterLockHeld, "H2");