Mercurial > pub > ImplabNet
diff Implab.Test/AsyncTests.cs @ 136:e9e7940c7d98 v2
shared locks + tests
author | cin |
---|---|
date | Mon, 16 Feb 2015 01:14:09 +0300 |
parents | f803565868a4 |
children | f75cfa58e3d4 |
line wrap: on
line diff
--- a/Implab.Test/AsyncTests.cs Fri Feb 13 02:08:01 2015 +0300 +++ b/Implab.Test/AsyncTests.cs Mon Feb 16 01:14:09 2015 +0300 @@ -774,6 +774,79 @@ Assert.IsTrue(pSurvive.Join()); } } + + [TestMethod] + public void SharedLockTest() { + var l = new SharedLock(); + int shared = 0; + int exclusive = 0; + var s1 = new Signal(); + var log = new AsyncQueue<string>(); + + try { + AsyncPool.RunThread( + () => { + log.Enqueue("Reader #1 started"); + try { + l.LockShared(); + log.Enqueue("Reader #1 lock got"); + if (Interlocked.Increment(ref shared) == 2) + s1.Set(); + s1.Wait(); + log.Enqueue("Reader #1 finished"); + Interlocked.Decrement(ref shared); + } finally { + l.Release(); + log.Enqueue("Reader #1 lock released"); + } + }, + () => { + log.Enqueue("Reader #2 started"); + + try { + l.LockShared(); + log.Enqueue("Reader #2 lock got"); + + if (Interlocked.Increment(ref shared) == 2) + s1.Set(); + s1.Wait(); + log.Enqueue("Reader #2 upgrading to writer"); + Interlocked.Decrement(ref shared); + l.Upgrade(); + log.Enqueue("Reader #2 upgraded"); + + Assert.AreEqual(1, Interlocked.Increment(ref exclusive)); + Assert.AreEqual(0, shared); + log.Enqueue("Reader #2 finished"); + Interlocked.Decrement(ref exclusive); + } finally { + l.Release(); + log.Enqueue("Reader #2 lock released"); + } + }, + () => { + log.Enqueue("Writer #1 started"); + try { + l.LockExclusive(); + log.Enqueue("Writer #1 got the lock"); + Assert.AreEqual(1, Interlocked.Increment(ref exclusive)); + Interlocked.Decrement(ref exclusive); + log.Enqueue("Writer #1 is finished"); + } finally { + l.Release(); + log.Enqueue("Writer #1 lock released"); + } + } + ).Bundle().Join(1000); + log.Enqueue("Done"); + } catch(Exception error) { + log.Enqueue(error.Message); + throw; + } finally { + foreach (var m in log) + Console.WriteLine(m); + } + } } }