public static void ReadersWaitingOnWaitingWriterTest()
{
var trwl = new TestReaderWriterLock();
trwl.AcquireReaderLock();
var waitingWriterReady = new AutoResetEvent(false);
var continueWaitingWriter = new AutoResetEvent(false);
Action waitForWaitingWriter;
Thread waitingWriter =
ThreadTestHelpers.CreateGuardedThread(out waitForWaitingWriter, () =>
{
trwl.AcquireWriterLock();
waitingWriterReady.Set();
continueWaitingWriter.CheckedWait();
trwl.ReleaseWriterLock();
});
waitingWriter.IsBackground = true;
waitingWriter.Start();
ThreadTestHelpers.WaitForCondition(() => (waitingWriter.ThreadState & ThreadState.WaitSleepJoin) != 0);
Action acquireReleaseReaderLock =
() =>
{
trwl.AcquireReaderLock();
trwl.ReleaseReaderLock();
};
Action waitForWaitingReader1, waitForWaitingReader2;
Thread waitingReader1 = ThreadTestHelpers.CreateGuardedThread(out waitForWaitingReader1, acquireReleaseReaderLock);
Thread waitingReader2 = ThreadTestHelpers.CreateGuardedThread(out waitForWaitingReader2, acquireReleaseReaderLock);
waitingReader1.IsBackground = true;
waitingReader2.IsBackground = true;
waitingReader1.Start();
waitingReader2.Start();
ThreadTestHelpers.WaitForCondition(() => (waitingReader1.ThreadState & ThreadState.WaitSleepJoin) != 0);
ThreadTestHelpers.WaitForCondition(() => (waitingReader2.ThreadState & ThreadState.WaitSleepJoin) != 0);
// Releasing the read lock releases the waiting writer
trwl.ReleaseReaderLock();
waitingWriterReady.CheckedWait();
// Releasing the now-writer's write lock releases all waiting readers
continueWaitingWriter.Set();
waitForWaitingWriter();
waitForWaitingReader1();
waitForWaitingReader2();
trwl.Dispose();
}