public void TestCheckingWaitPulseOwnership() { var monitor = new MonitorSimple(); var finished = 0; AssertEx.Throws<SynchronizationLockException>(() => { monitor.Wait(); }); AssertEx.Throws<SynchronizationLockException>(() => { monitor.Pulse(); }); AssertEx.Throws<SynchronizationLockException>(() => { monitor.PulseAll(); }); var th = new Thread(() => { monitor.Enter(); while (finished == 0) { } }) { IsBackground = true }; th.Start(); WaitAlittle(); // other thread has lock AssertEx.Throws<SynchronizationLockException>(() => { monitor.Wait(); }); AssertEx.Throws<SynchronizationLockException>(() => { monitor.Pulse(); }); AssertEx.Throws<SynchronizationLockException>(() => { monitor.PulseAll(); }); Thread.VolatileWrite(ref finished, 1); }
public void TestWait() { var e = new ManualResetEvent(false); var m = new MonitorSimple(); var testValue = 0; var th1 = new Thread(() => { m.Enter(); testValue = 1; e.WaitOne(); m.Wait(); testValue = 2; m.Exit(); }) { Name = "th1" }; var th2 = new Thread(() => { m.Enter(); testValue = 100; m.Exit(); }) { Name = "th2" }; th1.Start(); WaitAlittle(); th2.Start(); WaitAlittle(); Assert.AreEqual(1, testValue); e.Set(); WaitAlittle(); Assert.AreEqual(100, testValue); m.Enter(); m.PulseAll(); m.Exit(); WaitAlittle(); Assert.AreEqual(2, testValue); }
public void TestStressWait() { const int iterations = 1000000; const int doHardWorkBeforeEachNthProducing = iterations / 100; var threadCount = Environment.ProcessorCount; var src = 0; var dst = 0; var addingCompleted = false; var m = new MonitorSimple(); var readers = RunSimultanously(threadCount, () => { while (true) { using (m.GetLocked()) using (m.GetLocked()) using (m.GetLocked()) { while (src == 0 && !addingCompleted) m.Wait(); if (addingCompleted && src == 0) break; src = src - 1; dst = dst + 1; } } }, false); RunSimultanously(threadCount, () => { for (var i = 0; i < iterations; i++) { if (i % doHardWorkBeforeEachNthProducing == 0) DoHardWork(); using (m.GetLocked()) using (m.GetLocked()) //for extra stressing { src = src + 1; // such a weird construct is for extra stressing if (i % 2 == 0) m.Pulse(); else m.PulseAll(); } } }, true); using (m.GetLocked()) { addingCompleted = true; m.PulseAll(); } readers.ForEach(r => r.Join()); var expected = Enumerable.Repeat(1, iterations).Sum() * threadCount; Assert.AreEqual(expected, dst); }