Copied remotely
[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]\r
17         public class ReaderWriterLockTest : Assertion\r
18         {\r
19                 ReaderWriterLock rwlock;\r
20                 \r
21                 class ThreadRunner\r
22                 {\r
23                         public ThreadStart SecondaryThread;\r
24                         public Exception ResultException;\r
25                         public Thread RunningThread;\r
26                         \r
27                         public void Run ()\r
28                         {\r
29                                 try\r
30                                 {\r
31                                         SecondaryThread();\r
32                                 }\r
33                                 catch (Exception ex)\r
34                                 {\r
35                                         ResultException = ex;\r
36                                 }\r
37                         }\r
38                         \r
39                         public void Join ()\r
40                         {\r
41                                 RunningThread.Join (5000);\r
42                                 if (ResultException != null) throw ResultException;\r
43                         }\r
44                 }\r
45                 \r
46                 void RunThread (ThreadStart ts)\r
47                 {\r
48                         ThreadRunner tr = StartThread (ts);\r
49                         tr.Join ();\r
50                 }\r
51                 \r
52                 ThreadRunner StartThread (ThreadStart ts)\r
53                 {\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
58                         t.Start ();\r
59                         return tr;\r
60                 }\r
61                 \r
62                 [Test]
63                 public void TestIsReaderLockHeld ()\r
64                 {\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
71                 }\r
72                 \r
73                 private void IsReaderLockHeld_2 ()\r
74                 {\r
75                         Assert ("a3", !rwlock.IsReaderLockHeld);\r
76                 }\r
77                 \r
78                 [Test]\r
79                 public void TestIsWriterLockHeld ()\r
80                 {\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
87                 }\r
88                 \r
89                 private void IsWriterLockHeld_2 ()\r
90                 {\r
91                         Assert ("a3", !rwlock.IsWriterLockHeld);\r
92                 }\r
93                                 \r
94                 [Test]\r
95                 public void TestAcquireLocks ()\r
96                 {\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
104                         \r
105                         RunThread (new ThreadStart (AcquireLock_writerFails));\r
106                         rwlock.ReleaseReaderLock ();\r
107                         Assert ("a6", !rwlock.IsReaderLockHeld);\r
108                         \r
109                         RunThread (new ThreadStart (AcquireLock_writerWorks));\r
110                         \r
111                         rwlock.AcquireWriterLock (200);\r
112                         RunThread (new ThreadStart (AcquireLock_writerFails));\r
113                         RunThread (new ThreadStart (AcquireLock_readerFails));\r
114                         rwlock.ReleaseWriterLock ();\r
115                 }\r
116                 \r
117                 void AcquireLock_readerWorks ()\r
118                 {\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
125                 }\r
126                 \r
127                 void AcquireLock_writerFails ()\r
128                 {\r
129                         try\r
130                         {\r
131                                 rwlock.AcquireWriterLock (200);\r
132                                 rwlock.ReleaseWriterLock ();\r
133                                 throw new Exception ("Should not get writer lock");\r
134                         }\r
135                         catch (Exception)\r
136                         {\r
137                         }\r
138                 }\r
139                 \r
140                 void AcquireLock_writerWorks ()\r
141                 {\r
142                         rwlock.AcquireWriterLock (200);\r
143                         rwlock.ReleaseWriterLock ();\r
144                 }\r
145                 \r
146                 void AcquireLock_readerFails ()\r
147                 {\r
148                         try\r
149                         {\r
150                                 rwlock.AcquireReaderLock (200);\r
151                                 rwlock.ReleaseReaderLock ();\r
152                                 throw new Exception ("Should not get reader lock");\r
153                         }\r
154                         catch (Exception)\r
155                         {\r
156                         }\r
157                 }\r
158                 \r
159                 [Test]\r
160                 public void TestReleaseRestoreReaderLock ()\r
161                 {\r
162                         rwlock = new ReaderWriterLock ();\r
163                         rwlock.AcquireReaderLock (500);\r
164                         rwlock.AcquireReaderLock (500);\r
165                         Assert ("r1", rwlock.IsReaderLockHeld);\r
166                         \r
167                         LockCookie co = rwlock.ReleaseLock ();\r
168                         RunThread (new ThreadStart (AcquireLock_writerWorks));\r
169                         \r
170                         rwlock.RestoreLock (ref co);\r
171                         RunThread (new ThreadStart (AcquireLock_writerFails));\r
172                         \r
173                         rwlock.ReleaseReaderLock ();\r
174                         Assert ("r2", rwlock.IsReaderLockHeld);\r
175                         rwlock.ReleaseReaderLock ();\r
176                         Assert ("r3", !rwlock.IsReaderLockHeld);\r
177                 }\r
178                 \r
179                 [Test]\r
180                 public void TestReleaseRestoreWriterLock ()\r
181                 {\r
182                         rwlock = new ReaderWriterLock ();\r
183                         rwlock.AcquireWriterLock (500);\r
184                         rwlock.AcquireWriterLock (500);\r
185                         Assert ("w1", rwlock.IsWriterLockHeld);\r
186                         \r
187                         LockCookie co = rwlock.ReleaseLock ();\r
188                         RunThread (new ThreadStart (AcquireLock_readerWorks));\r
189                         \r
190                         rwlock.RestoreLock (ref co);\r
191                         RunThread (new ThreadStart (AcquireLock_readerFails));\r
192                         \r
193                         rwlock.ReleaseWriterLock ();\r
194                         Assert ("w2", rwlock.IsWriterLockHeld);\r
195                         rwlock.ReleaseWriterLock ();\r
196                         Assert ("w3", !rwlock.IsWriterLockHeld);\r
197                 }\r
198                 \r
199                 [Test]\r
200                 public void TestUpgradeDowngradeLock ()\r
201                 {\r
202                         rwlock = new ReaderWriterLock ();\r
203                         rwlock.AcquireReaderLock (200);\r
204                         rwlock.AcquireReaderLock (200);\r
205                         \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
210                         \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
215                         \r
216                         rwlock.ReleaseReaderLock ();\r
217                         Assert ("u5", rwlock.IsReaderLockHeld);\r
218                         rwlock.ReleaseReaderLock ();\r
219                         Assert ("u6", !rwlock.IsReaderLockHeld);\r
220                 }\r
221                 \r
222                 [Test]\r
223                 public void TestReaderInsideWriter ()\r
224                 {\r
225                         // Reader acquires and releases work like the writer equivalent\r
226                         \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
244                 }\r
245                 \r
246                 [Test]\r
247                 public void TestReaderMustWaitWriter ()\r
248                 {\r
249                         // A thread cannot get the reader lock if there are other threads\r
250                         // waiting for the writer lock.\r
251                         \r
252                         rwlock = new ReaderWriterLock ();\r
253                         rwlock.AcquireWriterLock (200);\r
254                         \r
255                         ThreadRunner tr = StartThread (new ThreadStart (ReaderMustWaitWriter_2));\r
256                         Thread.Sleep (200);\r
257                         \r
258                         RunThread (new ThreadStart (AcquireLock_readerFails));\r
259                         \r
260                         rwlock.ReleaseReaderLock ();\r
261                         tr.Join ();\r
262                 }\r
263                 \r
264                 void ReaderMustWaitWriter_2 ()\r
265                 {\r
266                         rwlock.AcquireWriterLock (2000);\r
267                         rwlock.ReleaseWriterLock ();\r
268                 }\r
269                 \r
270                 [Test]\r
271                 public void TestBug_55911 ()\r
272                 {\r
273                         rwlock = new ReaderWriterLock ();\r
274                         \r
275                         rwlock.AcquireReaderLock (Timeout.Infinite);\r
276                         try {\r
277                                 LockCookie lc = rwlock.UpgradeToWriterLock (Timeout.Infinite);\r
278                         }\r
279                         finally { rwlock.ReleaseReaderLock(); }\r
280                         \r
281                         rwlock.AcquireReaderLock (Timeout.Infinite);\r
282                         try {\r
283                                 LockCookie lc = rwlock.UpgradeToWriterLock (Timeout.Infinite);\r
284                         }\r
285                         finally { rwlock.ReleaseReaderLock(); }\r
286                 }\r
287                 \r
288                 [Test]\r
289                 public void TestBug_55909 ()\r
290                 {\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
295                         try {\r
296                                 LockCookie lc = rwlock.UpgradeToWriterLock (Timeout.Infinite);\r
297                                 Thread.Sleep (500);\r
298                         }\r
299                         finally { rwlock.ReleaseReaderLock(); }\r
300                         \r
301                         tr.Join ();\r
302                 }\r
303                 \r
304                 public void Bug_55909_Thread2 ()\r
305                 {\r
306                         rwlock.AcquireReaderLock(Timeout.Infinite);\r
307                         try {\r
308                                 Thread.Sleep (1000);\r
309                                 LockCookie lc = rwlock.UpgradeToWriterLock (Timeout.Infinite);\r
310                                 Thread.Sleep (500);\r
311                         }\r
312                         finally { rwlock.ReleaseReaderLock(); }\r
313                 }\r
314                 \r
315                 [Test]\r
316                 public void TestBug_55909_bis ()\r
317                 {\r
318                         rwlock = new ReaderWriterLock ();\r
319                         ThreadRunner tr1 = StartThread (new ThreadStart(Bug_55909_bis_ReaderWriter));\r
320                         Thread.Sleep(100);\r
321                         ThreadRunner tr2 = StartThread (new ThreadStart(Bug_55909_bis_Reader));\r
322                         Thread.Sleep(100);\r
323                         ThreadRunner tr3 = StartThread (new ThreadStart(Bug_55909_bis_Writer));\r
324                         Thread.Sleep(100);\r
325                         ThreadRunner tr4 = StartThread (new ThreadStart(Bug_55909_bis_Reader));\r
326                         tr1.Join ();\r
327                         tr2.Join ();\r
328                         tr3.Join ();\r
329                         tr4.Join ();\r
330                 }\r
331                 \r
332                 void Bug_55909_bis_Reader ()\r
333                 {\r
334                         rwlock.AcquireReaderLock(-1);\r
335                         Thread.Sleep(2000);\r
336                         rwlock.ReleaseReaderLock();\r
337                 }\r
338 \r
339                 void Bug_55909_bis_ReaderWriter ()\r
340                 {\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
346                 }\r
347 \r
348                 void Bug_55909_bis_Writer ()\r
349                 {\r
350                         rwlock.AcquireWriterLock(-1);\r
351                         rwlock.ReleaseWriterLock();\r
352                 }\r
353                 \r
354         }\r
355 }