2005-04-12 Dick Porter <dick@ximian.com>
[mono.git] / mcs / class / corlib / Test / System.Threading / ReaderWriterLockTest.cs
1 //\r
2 // ReaderWriterLockTest.cs - NUnit Test Cases for System.Threading.ReaderWriterLock\r
3 //\r
4 // Author:\r
5 //   Lluis Sanchez Gual (lluis@ximian.com)\r
6 //\r
7 // (C) 2004 Novell, Inc (http://www.novell.com)\r
8 // \r
9 \r
10 using NUnit.Framework;\r
11 using System;\r
12 using System.Threading;\r
13 \r
14 namespace MonoTests.System.Threading\r
15 {\r
16         [TestFixture]
17         [Category ("NotWorking")]
18         public class ReaderWriterLockTest : Assertion\r
19         {\r
20                 ReaderWriterLock rwlock;\r
21                 \r
22                 class ThreadRunner\r
23                 {\r
24                         public ThreadStart SecondaryThread;\r
25                         public Exception ResultException;\r
26                         public Thread RunningThread;\r
27                         \r
28                         public void Run ()\r
29                         {\r
30                                 try\r
31                                 {\r
32                                         SecondaryThread();\r
33                                 }\r
34                                 catch (Exception ex)\r
35                                 {\r
36                                         ResultException = ex;\r
37                                 }\r
38                         }\r
39                         \r
40                         public void Join ()\r
41                         {\r
42                                 RunningThread.Join (5000);\r
43                                 if (ResultException != null) throw ResultException;\r
44                         }\r
45                 }\r
46                 \r
47                 void RunThread (ThreadStart ts)\r
48                 {\r
49                         ThreadRunner tr = StartThread (ts);\r
50                         tr.Join ();\r
51                 }\r
52                 \r
53                 ThreadRunner StartThread (ThreadStart ts)\r
54                 {\r
55                         ThreadRunner tr = new ThreadRunner();\r
56                         tr.SecondaryThread = ts;\r
57                         Thread t = new Thread (new ThreadStart (tr.Run));\r
58                         tr.RunningThread = t;\r
59                         t.Start ();\r
60                         return tr;\r
61                 }\r
62                 \r
63                 [Test]
64                 public void TestIsReaderLockHeld ()\r
65                 {\r
66                         rwlock = new ReaderWriterLock ();\r
67                         Assert ("a1", !rwlock.IsReaderLockHeld);\r
68                         rwlock.AcquireReaderLock (500);\r
69                         Assert ("a2", rwlock.IsReaderLockHeld);\r
70                         RunThread (new ThreadStart (IsReaderLockHeld_2));\r
71                         rwlock.ReleaseReaderLock ();\r
72                 }\r
73                 \r
74                 private void IsReaderLockHeld_2 ()\r
75                 {\r
76                         Assert ("a3", !rwlock.IsReaderLockHeld);\r
77                 }\r
78                 \r
79                 [Test]\r
80                 public void TestIsWriterLockHeld ()\r
81                 {\r
82                         rwlock = new ReaderWriterLock ();\r
83                         Assert ("a1", !rwlock.IsWriterLockHeld);\r
84                         rwlock.AcquireWriterLock (500);\r
85                         Assert ("a2", rwlock.IsWriterLockHeld);\r
86                         RunThread (new ThreadStart (IsWriterLockHeld_2));\r
87                         rwlock.ReleaseWriterLock ();\r
88                 }\r
89                 \r
90                 private void IsWriterLockHeld_2 ()\r
91                 {\r
92                         Assert ("a3", !rwlock.IsWriterLockHeld);\r
93                 }\r
94                                 \r
95                 [Test]\r
96                 public void TestAcquireLocks ()\r
97                 {\r
98                         rwlock = new ReaderWriterLock ();\r
99                         rwlock.AcquireReaderLock (500);\r
100                         rwlock.AcquireReaderLock (500);\r
101                         rwlock.ReleaseReaderLock ();\r
102                         Assert ("a1", rwlock.IsReaderLockHeld);                 \r
103                         RunThread (new ThreadStart (AcquireLock_readerWorks));\r
104                         Assert ("a2", rwlock.IsReaderLockHeld);\r
105                         \r
106                         RunThread (new ThreadStart (AcquireLock_writerFails));\r
107                         rwlock.ReleaseReaderLock ();\r
108                         Assert ("a6", !rwlock.IsReaderLockHeld);\r
109                         \r
110                         RunThread (new ThreadStart (AcquireLock_writerWorks));\r
111                         \r
112                         rwlock.AcquireWriterLock (200);\r
113                         RunThread (new ThreadStart (AcquireLock_writerFails));\r
114                         RunThread (new ThreadStart (AcquireLock_readerFails));\r
115                         rwlock.ReleaseWriterLock ();\r
116                 }\r
117                 \r
118                 void AcquireLock_readerWorks ()\r
119                 {\r
120                         rwlock.AcquireReaderLock (200);\r
121                         rwlock.AcquireReaderLock (200);\r
122                         rwlock.ReleaseReaderLock ();\r
123                         Assert ("a3", rwlock.IsReaderLockHeld);\r
124                         rwlock.ReleaseReaderLock ();\r
125                         Assert ("a4", !rwlock.IsReaderLockHeld);\r
126                 }\r
127                 \r
128                 void AcquireLock_writerFails ()\r
129                 {\r
130                         try\r
131                         {\r
132                                 rwlock.AcquireWriterLock (200);\r
133                                 rwlock.ReleaseWriterLock ();\r
134                                 throw new Exception ("Should not get writer lock");\r
135                         }\r
136                         catch (Exception)\r
137                         {\r
138                         }\r
139                 }\r
140                 \r
141                 void AcquireLock_writerWorks ()\r
142                 {\r
143                         rwlock.AcquireWriterLock (200);\r
144                         rwlock.ReleaseWriterLock ();\r
145                 }\r
146                 \r
147                 void AcquireLock_readerFails ()\r
148                 {\r
149                         try\r
150                         {\r
151                                 rwlock.AcquireReaderLock (200);\r
152                                 rwlock.ReleaseReaderLock ();\r
153                                 throw new Exception ("Should not get reader lock");\r
154                         }\r
155                         catch (Exception)\r
156                         {\r
157                         }\r
158                 }\r
159                 \r
160                 [Test]\r
161                 public void TestReleaseRestoreReaderLock ()\r
162                 {\r
163                         rwlock = new ReaderWriterLock ();\r
164                         rwlock.AcquireReaderLock (500);\r
165                         rwlock.AcquireReaderLock (500);\r
166                         Assert ("r1", rwlock.IsReaderLockHeld);\r
167                         \r
168                         LockCookie co = rwlock.ReleaseLock ();\r
169                         RunThread (new ThreadStart (AcquireLock_writerWorks));\r
170                         \r
171                         rwlock.RestoreLock (ref co);\r
172                         RunThread (new ThreadStart (AcquireLock_writerFails));\r
173                         \r
174                         rwlock.ReleaseReaderLock ();\r
175                         Assert ("r2", rwlock.IsReaderLockHeld);\r
176                         rwlock.ReleaseReaderLock ();\r
177                         Assert ("r3", !rwlock.IsReaderLockHeld);\r
178                 }\r
179                 \r
180                 [Test]\r
181                 public void TestReleaseRestoreWriterLock ()\r
182                 {\r
183                         rwlock = new ReaderWriterLock ();\r
184                         rwlock.AcquireWriterLock (500);\r
185                         rwlock.AcquireWriterLock (500);\r
186                         Assert ("w1", rwlock.IsWriterLockHeld);\r
187                         \r
188                         LockCookie co = rwlock.ReleaseLock ();\r
189                         RunThread (new ThreadStart (AcquireLock_readerWorks));\r
190                         \r
191                         rwlock.RestoreLock (ref co);\r
192                         RunThread (new ThreadStart (AcquireLock_readerFails));\r
193                         \r
194                         rwlock.ReleaseWriterLock ();\r
195                         Assert ("w2", rwlock.IsWriterLockHeld);\r
196                         rwlock.ReleaseWriterLock ();\r
197                         Assert ("w3", !rwlock.IsWriterLockHeld);\r
198                 }\r
199                 \r
200                 [Test]\r
201                 public void TestUpgradeDowngradeLock ()\r
202                 {\r
203                         rwlock = new ReaderWriterLock ();\r
204                         rwlock.AcquireReaderLock (200);\r
205                         rwlock.AcquireReaderLock (200);\r
206                         \r
207                         LockCookie co = rwlock.UpgradeToWriterLock (200);\r
208                         Assert ("u1", !rwlock.IsReaderLockHeld);\r
209                         Assert ("u2", rwlock.IsWriterLockHeld);\r
210                         RunThread (new ThreadStart (AcquireLock_writerFails));\r
211                         \r
212                         rwlock.DowngradeFromWriterLock (ref co);\r
213                         Assert ("u3", rwlock.IsReaderLockHeld);\r
214                         Assert ("u4", !rwlock.IsWriterLockHeld);\r
215                         RunThread (new ThreadStart (AcquireLock_readerWorks));\r
216                         \r
217                         rwlock.ReleaseReaderLock ();\r
218                         Assert ("u5", rwlock.IsReaderLockHeld);\r
219                         rwlock.ReleaseReaderLock ();\r
220                         Assert ("u6", !rwlock.IsReaderLockHeld);\r
221                 }\r
222                 \r
223                 [Test]\r
224                 public void TestReaderInsideWriter ()\r
225                 {\r
226                         // Reader acquires and releases work like the writer equivalent\r
227                         \r
228                         rwlock = new ReaderWriterLock ();\r
229                         rwlock.AcquireWriterLock (-1);\r
230                         rwlock.AcquireReaderLock (-1);\r
231                         Assert ("u1", !rwlock.IsReaderLockHeld);\r
232                         Assert ("u2", rwlock.IsWriterLockHeld);\r
233                         rwlock.AcquireReaderLock (-1);\r
234                         Assert ("u3", !rwlock.IsReaderLockHeld);\r
235                         Assert ("u4", rwlock.IsWriterLockHeld);\r
236                         rwlock.ReleaseWriterLock ();\r
237                         Assert ("u5", !rwlock.IsReaderLockHeld);\r
238                         Assert ("u6", rwlock.IsWriterLockHeld);\r
239                         rwlock.ReleaseReaderLock ();\r
240                         Assert ("u7", !rwlock.IsReaderLockHeld);\r
241                         Assert ("u8", rwlock.IsWriterLockHeld);\r
242                         rwlock.ReleaseReaderLock ();\r
243                         Assert ("u9", !rwlock.IsReaderLockHeld);\r
244                         Assert ("u10", !rwlock.IsWriterLockHeld);\r
245                 }\r
246                 \r
247                 [Test]\r
248                 public void TestReaderMustWaitWriter ()\r
249                 {\r
250                         // A thread cannot get the reader lock if there are other threads\r
251                         // waiting for the writer lock.\r
252                         \r
253                         rwlock = new ReaderWriterLock ();\r
254                         rwlock.AcquireWriterLock (200);\r
255                         \r
256                         ThreadRunner tr = StartThread (new ThreadStart (ReaderMustWaitWriter_2));\r
257                         Thread.Sleep (200);\r
258                         \r
259                         RunThread (new ThreadStart (AcquireLock_readerFails));\r
260                         \r
261                         rwlock.ReleaseReaderLock ();\r
262                         tr.Join ();\r
263                 }\r
264                 \r
265                 void ReaderMustWaitWriter_2 ()\r
266                 {\r
267                         rwlock.AcquireWriterLock (2000);\r
268                         rwlock.ReleaseWriterLock ();\r
269                 }\r
270                 \r
271                 [Test]\r
272                 public void TestBug_55911 ()\r
273                 {\r
274                         rwlock = new ReaderWriterLock ();\r
275                         \r
276                         rwlock.AcquireReaderLock (Timeout.Infinite);\r
277                         try {\r
278                                 LockCookie lc = rwlock.UpgradeToWriterLock (Timeout.Infinite);\r
279                         }\r
280                         finally { rwlock.ReleaseReaderLock(); }\r
281                         \r
282                         rwlock.AcquireReaderLock (Timeout.Infinite);\r
283                         try {\r
284                                 LockCookie lc = rwlock.UpgradeToWriterLock (Timeout.Infinite);\r
285                         }\r
286                         finally { rwlock.ReleaseReaderLock(); }\r
287                 }\r
288                 \r
289                 [Test]\r
290                 public void TestBug_55909 ()\r
291                 {\r
292                         rwlock = new ReaderWriterLock ();\r
293                         ThreadRunner tr = StartThread (new ThreadStart(Bug_55909_Thread2));\r
294                         Thread.Sleep (200);\r
295                         rwlock.AcquireReaderLock (Timeout.Infinite);\r
296                         try {\r
297                                 LockCookie lc = rwlock.UpgradeToWriterLock (Timeout.Infinite);\r
298                                 Thread.Sleep (500);\r
299                         }\r
300                         finally { rwlock.ReleaseReaderLock(); }\r
301                         \r
302                         tr.Join ();\r
303                 }\r
304                 \r
305                 public void Bug_55909_Thread2 ()\r
306                 {\r
307                         rwlock.AcquireReaderLock(Timeout.Infinite);\r
308                         try {\r
309                                 Thread.Sleep (1000);\r
310                                 LockCookie lc = rwlock.UpgradeToWriterLock (Timeout.Infinite);\r
311                                 Thread.Sleep (500);\r
312                         }\r
313                         finally { rwlock.ReleaseReaderLock(); }\r
314                 }\r
315                 \r
316                 [Test]\r
317                 public void TestBug_55909_bis ()\r
318                 {\r
319                         rwlock = new ReaderWriterLock ();\r
320                         ThreadRunner tr1 = StartThread (new ThreadStart(Bug_55909_bis_ReaderWriter));\r
321                         Thread.Sleep(100);\r
322                         ThreadRunner tr2 = StartThread (new ThreadStart(Bug_55909_bis_Reader));\r
323                         Thread.Sleep(100);\r
324                         ThreadRunner tr3 = StartThread (new ThreadStart(Bug_55909_bis_Writer));\r
325                         Thread.Sleep(100);\r
326                         ThreadRunner tr4 = StartThread (new ThreadStart(Bug_55909_bis_Reader));\r
327                         tr1.Join ();\r
328                         tr2.Join ();\r
329                         tr3.Join ();\r
330                         tr4.Join ();\r
331                 }\r
332                 \r
333                 void Bug_55909_bis_Reader ()\r
334                 {\r
335                         rwlock.AcquireReaderLock(-1);\r
336                         Thread.Sleep(2000);\r
337                         rwlock.ReleaseReaderLock();\r
338                 }\r
339 \r
340                 void Bug_55909_bis_ReaderWriter ()\r
341                 {\r
342                         rwlock.AcquireReaderLock(-1);\r
343                         LockCookie lc = rwlock.UpgradeToWriterLock(-1);\r
344                         Thread.Sleep(1000);\r
345                         rwlock.DowngradeFromWriterLock(ref lc);\r
346                         rwlock.ReleaseReaderLock();\r
347                 }\r
348 \r
349                 void Bug_55909_bis_Writer ()\r
350                 {\r
351                         rwlock.AcquireWriterLock(-1);\r
352                         rwlock.ReleaseWriterLock();\r
353                 }\r
354                 \r
355         }\r
356 }