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 // DISABLED due to random hangs. Do not renable until you can run this
18 // a few thousand times on an SMP box.
19 [Category ("NotWorking")]
20 public class ReaderWriterLockTest : Assertion
\r
22 ReaderWriterLock rwlock;
\r
26 public ThreadStart SecondaryThread;
\r
27 public Exception ResultException;
\r
28 public Thread RunningThread;
\r
36 catch (Exception ex)
\r
38 ResultException = ex;
\r
44 RunningThread.Join (5000);
\r
45 if (ResultException != null) throw ResultException;
\r
49 void RunThread (ThreadStart ts)
\r
51 ThreadRunner tr = StartThread (ts);
\r
55 ThreadRunner StartThread (ThreadStart ts)
\r
57 ThreadRunner tr = new ThreadRunner();
\r
58 tr.SecondaryThread = ts;
\r
59 Thread t = new Thread (new ThreadStart (tr.Run));
\r
60 tr.RunningThread = t;
\r
66 public void TestIsReaderLockHeld ()
\r
68 rwlock = new ReaderWriterLock ();
\r
69 Assert ("a1", !rwlock.IsReaderLockHeld);
\r
70 rwlock.AcquireReaderLock (500);
\r
71 Assert ("a2", rwlock.IsReaderLockHeld);
\r
72 RunThread (new ThreadStart (IsReaderLockHeld_2));
\r
73 rwlock.ReleaseReaderLock ();
\r
76 private void IsReaderLockHeld_2 ()
\r
78 Assert ("a3", !rwlock.IsReaderLockHeld);
\r
82 public void TestIsWriterLockHeld ()
\r
84 rwlock = new ReaderWriterLock ();
\r
85 Assert ("a1", !rwlock.IsWriterLockHeld);
\r
86 rwlock.AcquireWriterLock (500);
\r
87 Assert ("a2", rwlock.IsWriterLockHeld);
\r
88 RunThread (new ThreadStart (IsWriterLockHeld_2));
\r
89 rwlock.ReleaseWriterLock ();
\r
92 private void IsWriterLockHeld_2 ()
\r
94 Assert ("a3", !rwlock.IsWriterLockHeld);
\r
98 public void TestAcquireLocks ()
\r
100 rwlock = new ReaderWriterLock ();
\r
101 rwlock.AcquireReaderLock (500);
\r
102 rwlock.AcquireReaderLock (500);
\r
103 rwlock.ReleaseReaderLock ();
\r
104 Assert ("a1", rwlock.IsReaderLockHeld);
\r
105 RunThread (new ThreadStart (AcquireLock_readerWorks));
\r
106 Assert ("a2", rwlock.IsReaderLockHeld);
\r
108 RunThread (new ThreadStart (AcquireLock_writerFails));
\r
109 rwlock.ReleaseReaderLock ();
\r
110 Assert ("a6", !rwlock.IsReaderLockHeld);
\r
112 RunThread (new ThreadStart (AcquireLock_writerWorks));
\r
114 rwlock.AcquireWriterLock (200);
\r
115 RunThread (new ThreadStart (AcquireLock_writerFails));
\r
116 RunThread (new ThreadStart (AcquireLock_readerFails));
\r
117 rwlock.ReleaseWriterLock ();
\r
120 void AcquireLock_readerWorks ()
\r
122 rwlock.AcquireReaderLock (200);
\r
123 rwlock.AcquireReaderLock (200);
\r
124 rwlock.ReleaseReaderLock ();
\r
125 Assert ("a3", rwlock.IsReaderLockHeld);
\r
126 rwlock.ReleaseReaderLock ();
\r
127 Assert ("a4", !rwlock.IsReaderLockHeld);
\r
130 void AcquireLock_writerFails ()
\r
134 rwlock.AcquireWriterLock (200);
\r
135 rwlock.ReleaseWriterLock ();
\r
136 throw new Exception ("Should not get writer lock");
\r
143 void AcquireLock_writerWorks ()
\r
145 rwlock.AcquireWriterLock (200);
\r
146 rwlock.ReleaseWriterLock ();
\r
149 void AcquireLock_readerFails ()
\r
153 rwlock.AcquireReaderLock (200);
\r
154 rwlock.ReleaseReaderLock ();
\r
155 throw new Exception ("Should not get reader lock");
\r
163 public void TestReleaseRestoreReaderLock ()
\r
165 rwlock = new ReaderWriterLock ();
\r
166 rwlock.AcquireReaderLock (500);
\r
167 rwlock.AcquireReaderLock (500);
\r
168 Assert ("r1", rwlock.IsReaderLockHeld);
\r
170 LockCookie co = rwlock.ReleaseLock ();
\r
171 RunThread (new ThreadStart (AcquireLock_writerWorks));
\r
173 rwlock.RestoreLock (ref co);
\r
174 RunThread (new ThreadStart (AcquireLock_writerFails));
\r
176 rwlock.ReleaseReaderLock ();
\r
177 Assert ("r2", rwlock.IsReaderLockHeld);
\r
178 rwlock.ReleaseReaderLock ();
\r
179 Assert ("r3", !rwlock.IsReaderLockHeld);
\r
183 public void TestReleaseRestoreWriterLock ()
\r
185 rwlock = new ReaderWriterLock ();
\r
186 rwlock.AcquireWriterLock (500);
\r
187 rwlock.AcquireWriterLock (500);
\r
188 Assert ("w1", rwlock.IsWriterLockHeld);
\r
190 LockCookie co = rwlock.ReleaseLock ();
\r
191 RunThread (new ThreadStart (AcquireLock_readerWorks));
\r
193 rwlock.RestoreLock (ref co);
\r
194 RunThread (new ThreadStart (AcquireLock_readerFails));
\r
196 rwlock.ReleaseWriterLock ();
\r
197 Assert ("w2", rwlock.IsWriterLockHeld);
\r
198 rwlock.ReleaseWriterLock ();
\r
199 Assert ("w3", !rwlock.IsWriterLockHeld);
\r
203 public void TestUpgradeDowngradeLock ()
\r
205 rwlock = new ReaderWriterLock ();
\r
206 rwlock.AcquireReaderLock (200);
\r
207 rwlock.AcquireReaderLock (200);
\r
209 LockCookie co = rwlock.UpgradeToWriterLock (200);
\r
210 Assert ("u1", !rwlock.IsReaderLockHeld);
\r
211 Assert ("u2", rwlock.IsWriterLockHeld);
\r
212 RunThread (new ThreadStart (AcquireLock_writerFails));
\r
214 rwlock.DowngradeFromWriterLock (ref co);
\r
215 Assert ("u3", rwlock.IsReaderLockHeld);
\r
216 Assert ("u4", !rwlock.IsWriterLockHeld);
\r
217 RunThread (new ThreadStart (AcquireLock_readerWorks));
\r
219 rwlock.ReleaseReaderLock ();
\r
220 Assert ("u5", rwlock.IsReaderLockHeld);
\r
221 rwlock.ReleaseReaderLock ();
\r
222 Assert ("u6", !rwlock.IsReaderLockHeld);
\r
226 public void TestReaderInsideWriter ()
\r
228 // Reader acquires and releases work like the writer equivalent
\r
230 rwlock = new ReaderWriterLock ();
\r
231 rwlock.AcquireWriterLock (-1);
\r
232 rwlock.AcquireReaderLock (-1);
\r
233 Assert ("u1", !rwlock.IsReaderLockHeld);
\r
234 Assert ("u2", rwlock.IsWriterLockHeld);
\r
235 rwlock.AcquireReaderLock (-1);
\r
236 Assert ("u3", !rwlock.IsReaderLockHeld);
\r
237 Assert ("u4", rwlock.IsWriterLockHeld);
\r
238 rwlock.ReleaseWriterLock ();
\r
239 Assert ("u5", !rwlock.IsReaderLockHeld);
\r
240 Assert ("u6", rwlock.IsWriterLockHeld);
\r
241 rwlock.ReleaseReaderLock ();
\r
242 Assert ("u7", !rwlock.IsReaderLockHeld);
\r
243 Assert ("u8", rwlock.IsWriterLockHeld);
\r
244 rwlock.ReleaseReaderLock ();
\r
245 Assert ("u9", !rwlock.IsReaderLockHeld);
\r
246 Assert ("u10", !rwlock.IsWriterLockHeld);
\r
250 public void TestReaderMustWaitWriter ()
\r
252 // A thread cannot get the reader lock if there are other threads
\r
253 // waiting for the writer lock.
\r
255 rwlock = new ReaderWriterLock ();
\r
256 rwlock.AcquireWriterLock (200);
\r
258 ThreadRunner tr = StartThread (new ThreadStart (ReaderMustWaitWriter_2));
\r
259 Thread.Sleep (200);
\r
261 RunThread (new ThreadStart (AcquireLock_readerFails));
\r
263 rwlock.ReleaseReaderLock ();
\r
267 void ReaderMustWaitWriter_2 ()
\r
269 rwlock.AcquireWriterLock (2000);
\r
270 rwlock.ReleaseWriterLock ();
\r
274 public void TestBug_55911 ()
\r
276 rwlock = new ReaderWriterLock ();
\r
278 rwlock.AcquireReaderLock (Timeout.Infinite);
\r
280 LockCookie lc = rwlock.UpgradeToWriterLock (Timeout.Infinite);
\r
282 finally { rwlock.ReleaseReaderLock(); }
\r
284 rwlock.AcquireReaderLock (Timeout.Infinite);
\r
286 LockCookie lc = rwlock.UpgradeToWriterLock (Timeout.Infinite);
\r
288 finally { rwlock.ReleaseReaderLock(); }
\r
292 public void TestBug_55909 ()
\r
294 rwlock = new ReaderWriterLock ();
\r
295 ThreadRunner tr = StartThread (new ThreadStart(Bug_55909_Thread2));
\r
296 Thread.Sleep (200);
\r
297 rwlock.AcquireReaderLock (Timeout.Infinite);
\r
299 LockCookie lc = rwlock.UpgradeToWriterLock (Timeout.Infinite);
\r
300 Thread.Sleep (500);
\r
302 finally { rwlock.ReleaseReaderLock(); }
\r
307 public void Bug_55909_Thread2 ()
\r
309 rwlock.AcquireReaderLock(Timeout.Infinite);
\r
311 Thread.Sleep (1000);
\r
312 LockCookie lc = rwlock.UpgradeToWriterLock (Timeout.Infinite);
\r
313 Thread.Sleep (500);
\r
315 finally { rwlock.ReleaseReaderLock(); }
\r
319 public void TestBug_55909_bis ()
\r
321 rwlock = new ReaderWriterLock ();
\r
322 ThreadRunner tr1 = StartThread (new ThreadStart(Bug_55909_bis_ReaderWriter));
\r
324 ThreadRunner tr2 = StartThread (new ThreadStart(Bug_55909_bis_Reader));
\r
326 ThreadRunner tr3 = StartThread (new ThreadStart(Bug_55909_bis_Writer));
\r
328 ThreadRunner tr4 = StartThread (new ThreadStart(Bug_55909_bis_Reader));
\r
335 void Bug_55909_bis_Reader ()
\r
337 rwlock.AcquireReaderLock(-1);
\r
338 Thread.Sleep(2000);
\r
339 rwlock.ReleaseReaderLock();
\r
342 void Bug_55909_bis_ReaderWriter ()
\r
344 rwlock.AcquireReaderLock(-1);
\r
345 LockCookie lc = rwlock.UpgradeToWriterLock(-1);
\r
346 Thread.Sleep(1000);
\r
347 rwlock.DowngradeFromWriterLock(ref lc);
\r
348 rwlock.ReleaseReaderLock();
\r
351 void Bug_55909_bis_Writer ()
\r
353 rwlock.AcquireWriterLock(-1);
\r
354 rwlock.ReleaseWriterLock();
\r