| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467 |
- //
- // ReaderWriterLockTest.cs - NUnit Test Cases for System.Threading.ReaderWriterLock
- //
- // Author:
- // Lluis Sanchez Gual ([email protected])
- //
- // (C) 2004 Novell, Inc (http://www.novell.com)
- //
- using NUnit.Framework;
- using System;
- using System.Threading;
- namespace MonoTests.System.Threading
- {
- [TestFixture]
- public class ReaderWriterLockTest
- {
- ReaderWriterLock rwlock;
-
- class ThreadRunner
- {
- public ThreadStart SecondaryThread;
- public Exception ResultException;
- public Thread RunningThread;
-
- public void Run ()
- {
- try
- {
- SecondaryThread();
- }
- catch (Exception ex)
- {
- ResultException = ex;
- }
- }
-
- public void Join ()
- {
- RunningThread.Join (5000);
- if (ResultException != null) throw ResultException;
- }
- }
-
- void RunThread (ThreadStart ts)
- {
- ThreadRunner tr = StartThread (ts);
- tr.Join ();
- }
-
- ThreadRunner StartThread (ThreadStart ts)
- {
- ThreadRunner tr = new ThreadRunner();
- tr.SecondaryThread = ts;
- Thread t = new Thread (new ThreadStart (tr.Run));
- tr.RunningThread = t;
- t.Start ();
- return tr;
- }
-
- [Test]
- public void TestIsReaderLockHeld ()
- {
- rwlock = new ReaderWriterLock ();
- Assert.IsTrue (!rwlock.IsReaderLockHeld, "#1");
- rwlock.AcquireReaderLock (500);
- Assert.IsTrue (rwlock.IsReaderLockHeld, "#1");
- RunThread (new ThreadStart (IsReaderLockHeld_2));
- rwlock.ReleaseReaderLock ();
- }
-
- private void IsReaderLockHeld_2 ()
- {
- Assert.IsTrue (!rwlock.IsReaderLockHeld);
- }
-
- [Test]
- public void TestIsWriterLockHeld ()
- {
- rwlock = new ReaderWriterLock ();
- Assert.IsTrue (!rwlock.IsWriterLockHeld, "#1");
- rwlock.AcquireWriterLock (500);
- Assert.IsTrue (rwlock.IsWriterLockHeld, "#2");
- RunThread (new ThreadStart (IsWriterLockHeld_2));
- rwlock.ReleaseWriterLock ();
- }
-
- private void IsWriterLockHeld_2 ()
- {
- Assert.IsTrue (!rwlock.IsWriterLockHeld);
- }
-
- [Test]
- public void TestAcquireLocks ()
- {
- rwlock = new ReaderWriterLock ();
- rwlock.AcquireReaderLock (500);
- rwlock.AcquireReaderLock (500);
- rwlock.ReleaseReaderLock ();
- Assert.IsTrue (rwlock.IsReaderLockHeld, "#1");
- RunThread (new ThreadStart (AcquireLock_readerWorks));
- Assert.IsTrue (rwlock.IsReaderLockHeld);
-
- RunThread (new ThreadStart (AcquireLock_writerFails));
- rwlock.ReleaseReaderLock ();
- Assert.IsTrue (!rwlock.IsReaderLockHeld);
-
- RunThread (new ThreadStart (AcquireLock_writerWorks));
-
- rwlock.AcquireWriterLock (200);
- RunThread (new ThreadStart (AcquireLock_writerFails));
- RunThread (new ThreadStart (AcquireLock_readerFails));
- rwlock.ReleaseWriterLock ();
- }
-
- void AcquireLock_readerWorks ()
- {
- rwlock.AcquireReaderLock (200);
- rwlock.AcquireReaderLock (200);
- rwlock.ReleaseReaderLock ();
- Assert.IsTrue (rwlock.IsReaderLockHeld);
- rwlock.ReleaseReaderLock ();
- Assert.IsTrue (!rwlock.IsReaderLockHeld);
- }
-
- void AcquireLock_writerFails ()
- {
- try
- {
- rwlock.AcquireWriterLock (200);
- rwlock.ReleaseWriterLock ();
- throw new Exception ("Should not get writer lock");
- }
- catch (Exception)
- {
- }
- }
-
- void AcquireLock_writerWorks ()
- {
- rwlock.AcquireWriterLock (200);
- rwlock.ReleaseWriterLock ();
- }
-
- void AcquireLock_readerFails ()
- {
- try
- {
- rwlock.AcquireReaderLock (200);
- rwlock.ReleaseReaderLock ();
- throw new Exception ("Should not get reader lock");
- }
- catch (Exception)
- {
- }
- }
-
- [Test]
- public void TestReleaseRestoreReaderLock ()
- {
- rwlock = new ReaderWriterLock ();
- rwlock.AcquireReaderLock (500);
- rwlock.AcquireReaderLock (500);
- Assert.IsTrue (rwlock.IsReaderLockHeld);
-
- LockCookie co = rwlock.ReleaseLock ();
- RunThread (new ThreadStart (AcquireLock_writerWorks));
-
- rwlock.RestoreLock (ref co);
- RunThread (new ThreadStart (AcquireLock_writerFails));
-
- rwlock.ReleaseReaderLock ();
- Assert.IsTrue (rwlock.IsReaderLockHeld);
- rwlock.ReleaseReaderLock ();
- Assert.IsTrue (!rwlock.IsReaderLockHeld);
- }
-
- [Test]
- public void TestReleaseRestoreWriterLock ()
- {
- rwlock = new ReaderWriterLock ();
- rwlock.AcquireWriterLock (500);
- rwlock.AcquireWriterLock (500);
- Assert.IsTrue (rwlock.IsWriterLockHeld);
-
- LockCookie co = rwlock.ReleaseLock ();
- RunThread (new ThreadStart (AcquireLock_readerWorks));
-
- rwlock.RestoreLock (ref co);
- RunThread (new ThreadStart (AcquireLock_readerFails));
-
- rwlock.ReleaseWriterLock ();
- Assert.IsTrue (rwlock.IsWriterLockHeld);
- rwlock.ReleaseWriterLock ();
- Assert.IsTrue (!rwlock.IsWriterLockHeld);
- }
-
- [Test]
- public void TestUpgradeDowngradeLock ()
- {
- rwlock = new ReaderWriterLock ();
- rwlock.AcquireReaderLock (200);
- rwlock.AcquireReaderLock (200);
-
- LockCookie co = rwlock.UpgradeToWriterLock (200);
- Assert.IsTrue (!rwlock.IsReaderLockHeld);
- Assert.IsTrue (rwlock.IsWriterLockHeld);
- RunThread (new ThreadStart (AcquireLock_writerFails));
-
- rwlock.DowngradeFromWriterLock (ref co);
- Assert.IsTrue (rwlock.IsReaderLockHeld);
- Assert.IsTrue (!rwlock.IsWriterLockHeld);
- RunThread (new ThreadStart (AcquireLock_readerWorks));
-
- rwlock.ReleaseReaderLock ();
- Assert.IsTrue (rwlock.IsReaderLockHeld);
- rwlock.ReleaseReaderLock ();
- Assert.IsTrue (!rwlock.IsReaderLockHeld);
- }
-
- [Test]
- public void TestReaderInsideWriter ()
- {
- // Reader acquires and releases work like the writer equivalent
-
- rwlock = new ReaderWriterLock ();
- rwlock.AcquireWriterLock (-1);
- rwlock.AcquireReaderLock (-1);
- Assert.IsTrue (!rwlock.IsReaderLockHeld);
- Assert.IsTrue (rwlock.IsWriterLockHeld);
- rwlock.AcquireReaderLock (-1);
- Assert.IsTrue (!rwlock.IsReaderLockHeld);
- Assert.IsTrue (rwlock.IsWriterLockHeld);
- rwlock.ReleaseWriterLock ();
- Assert.IsTrue (!rwlock.IsReaderLockHeld);
- Assert.IsTrue (rwlock.IsWriterLockHeld);
- rwlock.ReleaseReaderLock ();
- Assert.IsTrue (!rwlock.IsReaderLockHeld);
- Assert.IsTrue (rwlock.IsWriterLockHeld);
- rwlock.ReleaseReaderLock ();
- Assert.IsTrue (!rwlock.IsReaderLockHeld);
- Assert.IsTrue (!rwlock.IsWriterLockHeld);
- }
-
- [Test]
- public void TestReaderMustWaitWriter ()
- {
- // A thread cannot get the reader lock if there are other threads
- // waiting for the writer lock.
-
- rwlock = new ReaderWriterLock ();
- rwlock.AcquireWriterLock (200);
-
- ThreadRunner tr = StartThread (new ThreadStart (ReaderMustWaitWriter_2));
- Thread.Sleep (200);
-
- RunThread (new ThreadStart (AcquireLock_readerFails));
-
- rwlock.ReleaseReaderLock ();
- tr.Join ();
- }
-
- void ReaderMustWaitWriter_2 ()
- {
- rwlock.AcquireWriterLock (2000);
- rwlock.ReleaseWriterLock ();
- }
-
- [Test]
- public void TestBug_55911 ()
- {
- rwlock = new ReaderWriterLock ();
-
- rwlock.AcquireReaderLock (Timeout.Infinite);
- try {
- LockCookie lc = rwlock.UpgradeToWriterLock (Timeout.Infinite);
- }
- finally { rwlock.ReleaseReaderLock(); }
-
- rwlock.AcquireReaderLock (Timeout.Infinite);
- try {
- LockCookie lc = rwlock.UpgradeToWriterLock (Timeout.Infinite);
- }
- finally { rwlock.ReleaseReaderLock(); }
- }
-
- [Test]
- public void TestBug_55909 ()
- {
- rwlock = new ReaderWriterLock ();
- ThreadRunner tr = StartThread (new ThreadStart(Bug_55909_Thread2));
- Thread.Sleep (200);
- rwlock.AcquireReaderLock (Timeout.Infinite);
- try {
- LockCookie lc = rwlock.UpgradeToWriterLock (Timeout.Infinite);
- Thread.Sleep (500);
- }
- finally { rwlock.ReleaseReaderLock(); }
-
- tr.Join ();
- }
-
- public void Bug_55909_Thread2 ()
- {
- rwlock.AcquireReaderLock(Timeout.Infinite);
- try {
- Thread.Sleep (1000);
- LockCookie lc = rwlock.UpgradeToWriterLock (Timeout.Infinite);
- Thread.Sleep (500);
- }
- finally { rwlock.ReleaseReaderLock(); }
- }
-
- [Test]
- public void TestBug_55909_bis ()
- {
- rwlock = new ReaderWriterLock ();
- ThreadRunner tr1 = StartThread (new ThreadStart(Bug_55909_bis_ReaderWriter));
- Thread.Sleep(100);
- ThreadRunner tr2 = StartThread (new ThreadStart(Bug_55909_bis_Reader));
- Thread.Sleep(100);
- ThreadRunner tr3 = StartThread (new ThreadStart(Bug_55909_bis_Writer));
- Thread.Sleep(100);
- ThreadRunner tr4 = StartThread (new ThreadStart(Bug_55909_bis_Reader));
- tr1.Join ();
- tr2.Join ();
- tr3.Join ();
- tr4.Join ();
- }
-
- void Bug_55909_bis_Reader ()
- {
- rwlock.AcquireReaderLock(-1);
- Thread.Sleep(2000);
- rwlock.ReleaseReaderLock();
- }
- void Bug_55909_bis_ReaderWriter ()
- {
- rwlock.AcquireReaderLock(-1);
- LockCookie lc = rwlock.UpgradeToWriterLock(-1);
- Thread.Sleep(1000);
- rwlock.DowngradeFromWriterLock(ref lc);
- rwlock.ReleaseReaderLock();
- }
- void Bug_55909_bis_Writer ()
- {
- rwlock.AcquireWriterLock(-1);
- rwlock.ReleaseWriterLock();
- }
-
- [Test]
- public void TestBug_475124 ()
- {
- LockCookie lc1, lc2;
- rwlock = new ReaderWriterLock ();
- Assert.IsFalse (rwlock.IsReaderLockHeld, "A1");
- Assert.IsFalse (rwlock.IsWriterLockHeld, "A2");
- rwlock.AcquireReaderLock (Timeout.Infinite);
- Assert.IsTrue (rwlock.IsReaderLockHeld, "B1");
- Assert.IsFalse (rwlock.IsWriterLockHeld, "B2");
- lc1 = rwlock.UpgradeToWriterLock (Timeout.Infinite);
- Assert.IsFalse (rwlock.IsReaderLockHeld, "C1");
- Assert.IsTrue (rwlock.IsWriterLockHeld, "C2");
- rwlock.AcquireReaderLock (Timeout.Infinite);
- Assert.IsFalse (rwlock.IsReaderLockHeld, "D1");
- Assert.IsTrue (rwlock.IsWriterLockHeld, "D2");
- lc2 = rwlock.UpgradeToWriterLock (Timeout.Infinite);
- Assert.IsFalse (rwlock.IsReaderLockHeld, "E1");
- Assert.IsTrue (rwlock.IsWriterLockHeld, "E2");
- rwlock.DowngradeFromWriterLock (ref lc2);
- Assert.IsFalse (rwlock.IsReaderLockHeld, "F1");
- Assert.IsTrue (rwlock.IsWriterLockHeld, "F2");
- rwlock.ReleaseReaderLock ();
- Assert.IsFalse (rwlock.IsReaderLockHeld, "G1");
- Assert.IsTrue (rwlock.IsWriterLockHeld, "G2");
- rwlock.DowngradeFromWriterLock (ref lc1);
- Assert.IsTrue (rwlock.IsReaderLockHeld, "H1");
- Assert.IsFalse (rwlock.IsWriterLockHeld, "H2");
- rwlock.ReleaseReaderLock ();
- Assert.IsFalse (rwlock.IsReaderLockHeld, "I1");
- Assert.IsFalse (rwlock.IsWriterLockHeld, "I2");
- }
- // this tests how downgrade works when multiple writer locks
- // are acquired - as long as the LockCookie referes to an
- // upgrade where there was already a writer lock, downgrade
- // behaves like a non-blocking ReleaseWriterLock
- [Test]
- public void DowngradeTest ()
- {
- LockCookie lc1, lc2, lc3, lc4;
- rwlock = new ReaderWriterLock ();
- rwlock.AcquireReaderLock (Timeout.Infinite);
- lc1 = rwlock.UpgradeToWriterLock (Timeout.Infinite);
- rwlock.AcquireReaderLock (Timeout.Infinite);
- lc2 = rwlock.UpgradeToWriterLock (Timeout.Infinite);
- rwlock.AcquireReaderLock (Timeout.Infinite);
- lc3 = rwlock.UpgradeToWriterLock (Timeout.Infinite);
- rwlock.AcquireReaderLock (Timeout.Infinite);
- lc4 = rwlock.UpgradeToWriterLock (Timeout.Infinite);
- rwlock.DowngradeFromWriterLock (ref lc2);
- Assert.IsFalse (rwlock.IsReaderLockHeld, "A1");
- Assert.IsTrue (rwlock.IsWriterLockHeld, "A2");
- rwlock.ReleaseReaderLock ();
- Assert.IsFalse (rwlock.IsReaderLockHeld, "B1");
- Assert.IsTrue (rwlock.IsWriterLockHeld, "B2");
- rwlock.DowngradeFromWriterLock (ref lc4);
- Assert.IsFalse (rwlock.IsReaderLockHeld, "C1");
- Assert.IsTrue (rwlock.IsWriterLockHeld, "C2");
- rwlock.ReleaseReaderLock ();
- Assert.IsFalse (rwlock.IsReaderLockHeld, "D1");
- Assert.IsTrue (rwlock.IsWriterLockHeld, "D2");
- rwlock.DowngradeFromWriterLock (ref lc3);
- Assert.IsFalse (rwlock.IsReaderLockHeld, "E1");
- Assert.IsTrue (rwlock.IsWriterLockHeld, "E2");
- rwlock.ReleaseReaderLock ();
- Assert.IsFalse (rwlock.IsReaderLockHeld, "F1");
- Assert.IsTrue (rwlock.IsWriterLockHeld, "F2");
- rwlock.DowngradeFromWriterLock (ref lc1);
- Assert.IsTrue (rwlock.IsReaderLockHeld, "G1");
- Assert.IsFalse (rwlock.IsWriterLockHeld, "G2");
- rwlock.ReleaseReaderLock ();
- Assert.IsFalse (rwlock.IsReaderLockHeld, "H1");
- Assert.IsFalse (rwlock.IsWriterLockHeld, "H2");
- }
- }
- }
|