2 // ReaderWriterLockTest.cs - NUnit Test Cases for System.Threading.ReaderWriterLock
\r
5 // Lluis Sanchez Gual (lluis@ximian.com)
\r
7 // (C) 2004 Novell, Inc (http://www.novell.com)
\r
10 using NUnit.Framework;
\r
12 using System.Threading;
\r
14 namespace MonoTests.System.Threading
\r
17 public class ReaderWriterLockTest : Assertion
\r
19 ReaderWriterLock rwlock;
\r
23 public ThreadStart SecondaryThread;
\r
24 public Exception ResultException;
\r
25 public Thread RunningThread;
\r
33 catch (Exception ex)
\r
35 ResultException = ex;
\r
41 RunningThread.Join (5000);
\r
42 if (ResultException != null) throw ResultException;
\r
46 void RunThread (ThreadStart ts)
\r
48 ThreadRunner tr = StartThread (ts);
\r
52 ThreadRunner StartThread (ThreadStart ts)
\r
54 ThreadRunner tr = new ThreadRunner();
\r
55 tr.SecondaryThread = ts;
\r
56 Thread t = new Thread (new ThreadStart (tr.Run));
\r
57 tr.RunningThread = t;
\r
63 public void TestIsReaderLockHeld ()
\r
65 rwlock = new ReaderWriterLock ();
\r
66 Assert ("a1", !rwlock.IsReaderLockHeld);
\r
67 rwlock.AcquireReaderLock (500);
\r
68 Assert ("a2", rwlock.IsReaderLockHeld);
\r
69 RunThread (new ThreadStart (IsReaderLockHeld_2));
\r
70 rwlock.ReleaseReaderLock ();
\r
73 private void IsReaderLockHeld_2 ()
\r
75 Assert ("a3", !rwlock.IsReaderLockHeld);
\r
79 public void TestIsWriterLockHeld ()
\r
81 rwlock = new ReaderWriterLock ();
\r
82 Assert ("a1", !rwlock.IsWriterLockHeld);
\r
83 rwlock.AcquireWriterLock (500);
\r
84 Assert ("a2", rwlock.IsWriterLockHeld);
\r
85 RunThread (new ThreadStart (IsWriterLockHeld_2));
\r
86 rwlock.ReleaseWriterLock ();
\r
89 private void IsWriterLockHeld_2 ()
\r
91 Assert ("a3", !rwlock.IsWriterLockHeld);
\r
95 public void TestAcquireLocks ()
\r
97 rwlock = new ReaderWriterLock ();
\r
98 rwlock.AcquireReaderLock (500);
\r
99 rwlock.AcquireReaderLock (500);
\r
100 rwlock.ReleaseReaderLock ();
\r
101 Assert ("a1", rwlock.IsReaderLockHeld);
\r
102 RunThread (new ThreadStart (AcquireLock_readerWorks));
\r
103 Assert ("a2", rwlock.IsReaderLockHeld);
\r
105 RunThread (new ThreadStart (AcquireLock_writerFails));
\r
106 rwlock.ReleaseReaderLock ();
\r
107 Assert ("a6", !rwlock.IsReaderLockHeld);
\r
109 RunThread (new ThreadStart (AcquireLock_writerWorks));
\r
111 rwlock.AcquireWriterLock (200);
\r
112 RunThread (new ThreadStart (AcquireLock_writerFails));
\r
113 RunThread (new ThreadStart (AcquireLock_readerFails));
\r
114 rwlock.ReleaseWriterLock ();
\r
117 void AcquireLock_readerWorks ()
\r
119 rwlock.AcquireReaderLock (200);
\r
120 rwlock.AcquireReaderLock (200);
\r
121 rwlock.ReleaseReaderLock ();
\r
122 Assert ("a3", rwlock.IsReaderLockHeld);
\r
123 rwlock.ReleaseReaderLock ();
\r
124 Assert ("a4", !rwlock.IsReaderLockHeld);
\r
127 void AcquireLock_writerFails ()
\r
131 rwlock.AcquireWriterLock (200);
\r
132 rwlock.ReleaseWriterLock ();
\r
133 throw new Exception ("Should not get writer lock");
\r
140 void AcquireLock_writerWorks ()
\r
142 rwlock.AcquireWriterLock (200);
\r
143 rwlock.ReleaseWriterLock ();
\r
146 void AcquireLock_readerFails ()
\r
150 rwlock.AcquireReaderLock (200);
\r
151 rwlock.ReleaseReaderLock ();
\r
152 throw new Exception ("Should not get reader lock");
\r
160 public void TestReleaseRestoreReaderLock ()
\r
162 rwlock = new ReaderWriterLock ();
\r
163 rwlock.AcquireReaderLock (500);
\r
164 rwlock.AcquireReaderLock (500);
\r
165 Assert ("r1", rwlock.IsReaderLockHeld);
\r
167 LockCookie co = rwlock.ReleaseLock ();
\r
168 RunThread (new ThreadStart (AcquireLock_writerWorks));
\r
170 rwlock.RestoreLock (ref co);
\r
171 RunThread (new ThreadStart (AcquireLock_writerFails));
\r
173 rwlock.ReleaseReaderLock ();
\r
174 Assert ("r2", rwlock.IsReaderLockHeld);
\r
175 rwlock.ReleaseReaderLock ();
\r
176 Assert ("r3", !rwlock.IsReaderLockHeld);
\r
180 public void TestReleaseRestoreWriterLock ()
\r
182 rwlock = new ReaderWriterLock ();
\r
183 rwlock.AcquireWriterLock (500);
\r
184 rwlock.AcquireWriterLock (500);
\r
185 Assert ("w1", rwlock.IsWriterLockHeld);
\r
187 LockCookie co = rwlock.ReleaseLock ();
\r
188 RunThread (new ThreadStart (AcquireLock_readerWorks));
\r
190 rwlock.RestoreLock (ref co);
\r
191 RunThread (new ThreadStart (AcquireLock_readerFails));
\r
193 rwlock.ReleaseWriterLock ();
\r
194 Assert ("w2", rwlock.IsWriterLockHeld);
\r
195 rwlock.ReleaseWriterLock ();
\r
196 Assert ("w3", !rwlock.IsWriterLockHeld);
\r
200 public void TestUpgradeDowngradeLock ()
\r
202 rwlock = new ReaderWriterLock ();
\r
203 rwlock.AcquireReaderLock (200);
\r
204 rwlock.AcquireReaderLock (200);
\r
206 LockCookie co = rwlock.UpgradeToWriterLock (200);
\r
207 Assert ("u1", !rwlock.IsReaderLockHeld);
\r
208 Assert ("u2", rwlock.IsWriterLockHeld);
\r
209 RunThread (new ThreadStart (AcquireLock_writerFails));
\r
211 rwlock.DowngradeFromWriterLock (ref co);
\r
212 Assert ("u3", rwlock.IsReaderLockHeld);
\r
213 Assert ("u4", !rwlock.IsWriterLockHeld);
\r
214 RunThread (new ThreadStart (AcquireLock_readerWorks));
\r
216 rwlock.ReleaseReaderLock ();
\r
217 Assert ("u5", rwlock.IsReaderLockHeld);
\r
218 rwlock.ReleaseReaderLock ();
\r
219 Assert ("u6", !rwlock.IsReaderLockHeld);
\r
223 public void TestReaderInsideWriter ()
\r
225 // Reader acquires and releases work like the writer equivalent
\r
227 rwlock = new ReaderWriterLock ();
\r
228 rwlock.AcquireWriterLock (-1);
\r
229 rwlock.AcquireReaderLock (-1);
\r
230 Assert ("u1", !rwlock.IsReaderLockHeld);
\r
231 Assert ("u2", rwlock.IsWriterLockHeld);
\r
232 rwlock.AcquireReaderLock (-1);
\r
233 Assert ("u3", !rwlock.IsReaderLockHeld);
\r
234 Assert ("u4", rwlock.IsWriterLockHeld);
\r
235 rwlock.ReleaseWriterLock ();
\r
236 Assert ("u5", !rwlock.IsReaderLockHeld);
\r
237 Assert ("u6", rwlock.IsWriterLockHeld);
\r
238 rwlock.ReleaseReaderLock ();
\r
239 Assert ("u7", !rwlock.IsReaderLockHeld);
\r
240 Assert ("u8", rwlock.IsWriterLockHeld);
\r
241 rwlock.ReleaseReaderLock ();
\r
242 Assert ("u9", !rwlock.IsReaderLockHeld);
\r
243 Assert ("u10", !rwlock.IsWriterLockHeld);
\r
247 public void TestReaderMustWaitWriter ()
\r
249 // A thread cannot get the reader lock if there are other threads
\r
250 // waiting for the writer lock.
\r
252 rwlock = new ReaderWriterLock ();
\r
253 rwlock.AcquireWriterLock (200);
\r
255 ThreadRunner tr = StartThread (new ThreadStart (ReaderMustWaitWriter_2));
\r
256 Thread.Sleep (200);
\r
258 RunThread (new ThreadStart (AcquireLock_readerFails));
\r
260 rwlock.ReleaseReaderLock ();
\r
264 void ReaderMustWaitWriter_2 ()
\r
266 rwlock.AcquireWriterLock (2000);
\r
267 rwlock.ReleaseWriterLock ();
\r
271 public void TestBug_55911 ()
\r
273 rwlock = new ReaderWriterLock ();
\r
275 rwlock.AcquireReaderLock (Timeout.Infinite);
\r
277 LockCookie lc = rwlock.UpgradeToWriterLock (Timeout.Infinite);
\r
279 finally { rwlock.ReleaseReaderLock(); }
\r
281 rwlock.AcquireReaderLock (Timeout.Infinite);
\r
283 LockCookie lc = rwlock.UpgradeToWriterLock (Timeout.Infinite);
\r
285 finally { rwlock.ReleaseReaderLock(); }
\r
289 public void TestBug_55909 ()
\r
291 rwlock = new ReaderWriterLock ();
\r
292 ThreadRunner tr = StartThread (new ThreadStart(Bug_55909_Thread2));
\r
293 Thread.Sleep (200);
\r
294 rwlock.AcquireReaderLock (Timeout.Infinite);
\r
296 LockCookie lc = rwlock.UpgradeToWriterLock (Timeout.Infinite);
\r
297 Thread.Sleep (500);
\r
299 finally { rwlock.ReleaseReaderLock(); }
\r
304 public void Bug_55909_Thread2 ()
\r
306 rwlock.AcquireReaderLock(Timeout.Infinite);
\r
308 Thread.Sleep (1000);
\r
309 LockCookie lc = rwlock.UpgradeToWriterLock (Timeout.Infinite);
\r
310 Thread.Sleep (500);
\r
312 finally { rwlock.ReleaseReaderLock(); }
\r
316 public void TestBug_55909_bis ()
\r
318 rwlock = new ReaderWriterLock ();
\r
319 ThreadRunner tr1 = StartThread (new ThreadStart(Bug_55909_bis_ReaderWriter));
\r
321 ThreadRunner tr2 = StartThread (new ThreadStart(Bug_55909_bis_Reader));
\r
323 ThreadRunner tr3 = StartThread (new ThreadStart(Bug_55909_bis_Writer));
\r
325 ThreadRunner tr4 = StartThread (new ThreadStart(Bug_55909_bis_Reader));
\r
332 void Bug_55909_bis_Reader ()
\r
334 rwlock.AcquireReaderLock(-1);
\r
335 Thread.Sleep(2000);
\r
336 rwlock.ReleaseReaderLock();
\r
339 void Bug_55909_bis_ReaderWriter ()
\r
341 rwlock.AcquireReaderLock(-1);
\r
342 LockCookie lc = rwlock.UpgradeToWriterLock(-1);
\r
343 Thread.Sleep(1000);
\r
344 rwlock.DowngradeFromWriterLock(ref lc);
\r
345 rwlock.ReleaseReaderLock();
\r
348 void Bug_55909_bis_Writer ()
\r
350 rwlock.AcquireWriterLock(-1);
\r
351 rwlock.ReleaseWriterLock();
\r