X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2Fcorlib%2FTest%2FSystem.Threading%2FReaderWriterLockTest.cs;h=ef398486a2abf25cc43216147d98e004e077f454;hb=055495c537473805859a4db627918347be547ee3;hp=7cb66350503b22e2a9fe699e002a9f77274b332a;hpb=d92027fad2228a4de513caf1b2dd36769d8205ed;p=mono.git diff --git a/mcs/class/corlib/Test/System.Threading/ReaderWriterLockTest.cs b/mcs/class/corlib/Test/System.Threading/ReaderWriterLockTest.cs index 7cb66350503..ef398486a2a 100644 --- a/mcs/class/corlib/Test/System.Threading/ReaderWriterLockTest.cs +++ b/mcs/class/corlib/Test/System.Threading/ReaderWriterLockTest.cs @@ -1,230 +1,467 @@ -// -// ReaderWriterLockTest.cs - NUnit Test Cases for System.Threading.ReaderWriterLock -// -// Author: -// Lluis Sanchez Gual (lluis@ximian.com) -// -// (C) 2004 Novell, Inc (http://www.novell.com) -// - -using NUnit.Framework; -using System; -using System.Threading; - -namespace MonoTests.System.Threading -{ - [TestFixture] - public class ReaderWriterLockTest : Assertion - { - ReaderWriterLock rwlock; - - Exception resultException; - ThreadStart secondaryThread; - - void StartThread (ThreadStart ts) - { - secondaryThread = ts; - resultException = null; - Thread t = new Thread (new ThreadStart (ThreadRunner)); - t.Start (); - t.Join (); - if (resultException != null) throw resultException; - } - - void ThreadRunner () - { - try - { - secondaryThread(); - } - catch (Exception ex) - { - resultException = ex; - } - } - +// +// ReaderWriterLockTest.cs - NUnit Test Cases for System.Threading.ReaderWriterLock +// +// Author: +// Lluis Sanchez Gual (lluis@ximian.com) +// +// (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 ("a1", !rwlock.IsReaderLockHeld); - rwlock.AcquireReaderLock (500); - Assert ("a2", rwlock.IsReaderLockHeld); - StartThread (new ThreadStart (IsReaderLockHeld_2)); - rwlock.ReleaseReaderLock (); - } - - private void IsReaderLockHeld_2 () - { - Assert ("a3", !rwlock.IsReaderLockHeld); - } - - [Test] - public void TestIsWriterLockHeld () - { - rwlock = new ReaderWriterLock (); - Assert ("a1", !rwlock.IsWriterLockHeld); - rwlock.AcquireWriterLock (500); - Assert ("a2", rwlock.IsWriterLockHeld); - StartThread (new ThreadStart (IsWriterLockHeld_2)); - rwlock.ReleaseWriterLock (); - } - - private void IsWriterLockHeld_2 () - { - Assert ("a3", !rwlock.IsWriterLockHeld); - } - - [Test] - public void TestAcquireLocks () - { - rwlock = new ReaderWriterLock (); - rwlock.AcquireReaderLock (500); - rwlock.AcquireReaderLock (500); - rwlock.ReleaseReaderLock (); - Assert ("a1", rwlock.IsReaderLockHeld); - StartThread (new ThreadStart (AcquireLock_readerWorks)); - Assert ("a2", rwlock.IsReaderLockHeld); - - StartThread (new ThreadStart (AcquireLock_writerFails)); - rwlock.ReleaseReaderLock (); - Assert ("a6", !rwlock.IsReaderLockHeld); - - StartThread (new ThreadStart (AcquireLock_writerWorks)); - - rwlock.AcquireWriterLock (200); - StartThread (new ThreadStart (AcquireLock_writerFails)); - StartThread (new ThreadStart (AcquireLock_readerFails)); - rwlock.ReleaseWriterLock (); - } - - void AcquireLock_readerWorks () - { - rwlock.AcquireReaderLock (200); - rwlock.AcquireReaderLock (200); - rwlock.ReleaseReaderLock (); - Assert ("a3", rwlock.IsReaderLockHeld); - rwlock.ReleaseReaderLock (); - Assert ("a4", !rwlock.IsReaderLockHeld); - } - - void AcquireLock_writerFails () - { - try - { - rwlock.AcquireWriterLock (200); - rwlock.ReleaseWriterLock (); - throw new Exception ("Should not get writer lock"); - } - catch (Exception ex) - { - } - } - - 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 ex) - { - } - } - - [Test] - public void TestReleaseRestoreReaderLock () - { - rwlock = new ReaderWriterLock (); - rwlock.AcquireReaderLock (500); - rwlock.AcquireReaderLock (500); - Assert ("r1", rwlock.IsReaderLockHeld); - - LockCookie co = rwlock.ReleaseLock (); - StartThread (new ThreadStart (AcquireLock_writerWorks)); - - rwlock.RestoreLock (ref co); - StartThread (new ThreadStart (AcquireLock_writerFails)); - - rwlock.ReleaseReaderLock (); - Assert ("r2", rwlock.IsReaderLockHeld); - rwlock.ReleaseReaderLock (); - Assert ("r3", !rwlock.IsReaderLockHeld); - } - - [Test] - public void TestReleaseRestoreWriterLock () - { - rwlock = new ReaderWriterLock (); - rwlock.AcquireWriterLock (500); - rwlock.AcquireWriterLock (500); - Assert ("w1", rwlock.IsWriterLockHeld); - - LockCookie co = rwlock.ReleaseLock (); - StartThread (new ThreadStart (AcquireLock_readerWorks)); - - rwlock.RestoreLock (ref co); - StartThread (new ThreadStart (AcquireLock_readerFails)); - - rwlock.ReleaseWriterLock (); - Assert ("w2", rwlock.IsWriterLockHeld); - rwlock.ReleaseWriterLock (); - Assert ("w3", !rwlock.IsWriterLockHeld); - } - - [Test] - public void TestUpgradeDowngradeLock () - { - rwlock = new ReaderWriterLock (); - rwlock.AcquireReaderLock (200); - rwlock.AcquireReaderLock (200); - - LockCookie co = rwlock.UpgradeToWriterLock (200); - Assert ("u1", !rwlock.IsReaderLockHeld); - Assert ("u2", rwlock.IsWriterLockHeld); - StartThread (new ThreadStart (AcquireLock_writerFails)); - - rwlock.DowngradeFromWriterLock (ref co); - Assert ("u3", rwlock.IsReaderLockHeld); - Assert ("u4", !rwlock.IsWriterLockHeld); - StartThread (new ThreadStart (AcquireLock_readerWorks)); - - rwlock.ReleaseReaderLock (); - Assert ("u5", rwlock.IsReaderLockHeld); - rwlock.ReleaseReaderLock (); - Assert ("u6", !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 ("u1", !rwlock.IsReaderLockHeld); - Assert ("u2", rwlock.IsWriterLockHeld); - rwlock.AcquireReaderLock (-1); - Assert ("u3", !rwlock.IsReaderLockHeld); - Assert ("u4", rwlock.IsWriterLockHeld); - rwlock.ReleaseWriterLock (); - Assert ("u5", !rwlock.IsReaderLockHeld); - Assert ("u6", rwlock.IsWriterLockHeld); - rwlock.ReleaseReaderLock (); - Assert ("u7", !rwlock.IsReaderLockHeld); - Assert ("u8", rwlock.IsWriterLockHeld); - rwlock.ReleaseReaderLock (); - Assert ("u9", !rwlock.IsReaderLockHeld); - Assert ("u10", !rwlock.IsWriterLockHeld); - } - } + 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"); + } + } }