public void TestInterruptOnDispose() { object syncObj = new object(); using (var testInst = new ConditionVariableOld(syncObj)) { int exitCount = 0; var task = Task.Run(() => { try { lock (syncObj) { testInst.Wait(_ => false, (object)null); } } catch (OperationInterruptedException) { } Interlocked.Increment(ref exitCount); }); TimingAssert.AreEqual(10000, 1, () => testInst.WaiterCount); testInst.Dispose(); TimingAssert.AreEqual(10000, 1, () => Volatile.Read(ref exitCount)); task.Wait(); } }
public void TestAllThreadWakeUpOnSignalAll() { object syncObj = new object(); using (var testInst = new ConditionVariableOld(syncObj)) { int exitCount = 0; int state = 0; List <Task> tasks = new List <Task>(); for (int i = 0; i < 6; i++) { var task = Task.Run(() => { lock (syncObj) { testInst.Wait(_ => { return(Volatile.Read(ref state) > 0); }, (object)null); Interlocked.Increment(ref exitCount); } }); tasks.Add(task); } TimingAssert.AreEqual(10000, 6, () => testInst.WaiterCount); Interlocked.Increment(ref state); lock (syncObj) { testInst.PulseAll(); } TimingAssert.AreEqual(10000, 0, () => testInst.WaiterCount); TimingAssert.AreEqual(10000, 6, () => Volatile.Read(ref exitCount)); } }
public void TestLongPredicateEstimatesOnceWithSmallTimeout() { object syncObj = new object(); using (var testInst = new ConditionVariableOld(syncObj)) { int result = 0; int estimCount = 0; var task = Task.Run(() => { lock (syncObj) { if (testInst.Wait(_ => { Interlocked.Increment(ref estimCount); Thread.Sleep(500); return(false); }, (object)null, 200)) { Interlocked.Exchange(ref result, 1); } else { Interlocked.Exchange(ref result, 2); } } }); lock (syncObj) { testInst.Pulse(); } TimingAssert.AreEqual(10000, 2, () => Volatile.Read(ref result)); Assert.AreEqual(1, Volatile.Read(ref estimCount)); } }
public void TestPredicateCalledOnTimeout() { object syncObj = new object(); using (var testInst = new ConditionVariableOld(syncObj)) { int result = 0; int state = 0; int called = 0; var task = Task.Run(() => { lock (syncObj) { if (testInst.Wait((s) => { Interlocked.Increment(ref called); return(Volatile.Read(ref state) > 0); }, new object(), 100)) { Interlocked.Exchange(ref result, 1); } else { Interlocked.Exchange(ref result, 2); } } }); TimingAssert.AreEqual(10000, 1, () => testInst.WaiterCount); TimingAssert.AreEqual(10000, 2, () => Volatile.Read(ref result)); TimingAssert.AreEqual(10000, 2, () => Volatile.Read(ref called)); } }
public void TestTimeoutWorks() { object syncObj = new object(); using (var testInst = new ConditionVariableOld(syncObj)) { int result = 0; var task = Task.Run(() => { lock (syncObj) { if (testInst.Wait(_ => false, (object)null, 500)) { Interlocked.Exchange(ref result, 1); } else { Interlocked.Exchange(ref result, 2); } } }); lock (syncObj) { testInst.Pulse(); } TimingAssert.AreEqual(10000, 2, () => Volatile.Read(ref result)); } }
public void TestNotificationReceived() { object syncObj = new object(); using (var testInst = new ConditionVariableOld(syncObj)) { int result = 0; var task = Task.Run(() => { lock (syncObj) { if (testInst.Wait(60000)) { Interlocked.Exchange(ref result, 1); } else { Interlocked.Exchange(ref result, 2); } } }); TimingAssert.AreEqual(10000, 1, () => testInst.WaiterCount); Assert.AreEqual(0, Volatile.Read(ref result)); lock (syncObj) { testInst.Pulse(); } TimingAssert.AreEqual(10000, 1, () => Volatile.Read(ref result)); } }
public void TestPulseThrowsIfExternalLockNotAcquired() { object syncObj = new object(); using (var testInst = new ConditionVariableOld(syncObj)) { testInst.Pulse(); } }
public void TestWaitWithPredicateThrowsIfExternalLockNotAcquired() { object syncObj = new object(); using (var testInst = new ConditionVariableOld(syncObj)) { testInst.Wait(_ => true, (object)null, 10); } }
public void TestPredicateCalledInsideLock() { object syncObj = new object(); using (var testInst = new ConditionVariableOld(syncObj)) { int result = 0; int estimCount = 0; int inMonitorCount = 0; int stopEstim = 0; var task = Task.Run(() => { lock (syncObj) { if (testInst.Wait(_ => { if (Monitor.IsEntered(syncObj)) { Interlocked.Increment(ref inMonitorCount); } Interlocked.Increment(ref estimCount); return(Volatile.Read(ref stopEstim) != 0); }, (object)null, 60000)) { Interlocked.Exchange(ref result, 1); } else { Interlocked.Exchange(ref result, 2); } } }); TimingAssert.AreEqual(10000, 1, () => testInst.WaiterCount); for (int i = 0; i < 20; i++) { lock (syncObj) { testInst.Pulse(); } Thread.Sleep(10); } Interlocked.Increment(ref stopEstim); lock (syncObj) { testInst.Pulse(); } TimingAssert.AreEqual(10000, 1, () => Volatile.Read(ref result)); Assert.IsTrue(Volatile.Read(ref estimCount) > 1); Assert.AreEqual(Volatile.Read(ref inMonitorCount), Volatile.Read(ref estimCount)); } }
public void TestStatePassedCorrectly() { object syncObj = new object(); lock (syncObj) { using (var testInst = new ConditionVariableOld(syncObj)) { object state = new object(); bool result = testInst.Wait((s) => { Assert.AreEqual(state, s); return(true); }, state, 100000); Assert.IsTrue(result); } } }
public void TestWaitWithPredicateThrowsIfExternalLockTakenRecursively() { object syncObj = new object(); using (var testInst = new ConditionVariableOld(syncObj)) { lock (syncObj) { lock (syncObj) { testInst.Wait(_ => false, (object)null, 10); } } } }
public void TestWaitThrowsIfExternalLockTakenRecursively() { object syncObj = new object(); using (var testInst = new ConditionVariableOld(syncObj)) { lock (syncObj) { lock (syncObj) { testInst.Wait(10); } } } }
public void TestAlwaysPositivePredicate() { object syncObj = new object(); lock (syncObj) { using (var testInst = new ConditionVariableOld(syncObj)) { int called = 0; bool result = testInst.Wait((s) => { called++; return(true); }, new object(), 100000); Assert.IsTrue(result); Assert.AreEqual(1, called); } } }
public void TestCancellationWorks() { object syncObj = new object(); using (var testInst = new ConditionVariableOld(syncObj)) { int result = 0; CancellationTokenSource tokenSrc = new CancellationTokenSource(); var task = Task.Run(() => { try { lock (syncObj) { if (testInst.Wait(_ => false, (object)null, 60000, tokenSrc.Token)) { Interlocked.Exchange(ref result, 1); } else { Interlocked.Exchange(ref result, 2); } } } catch (OperationCanceledException) { Interlocked.Exchange(ref result, 3); } }); lock (syncObj) { testInst.Pulse(); } Thread.Sleep(100); Assert.AreEqual(0, Volatile.Read(ref result)); tokenSrc.Cancel(); TimingAssert.AreEqual(10000, 3, () => Volatile.Read(ref result)); } }
public void TestNotificationWithPredicate() { object syncObj = new object(); using (var testInst = new ConditionVariableOld(syncObj)) { int result = 0; int state = 0; var task = Task.Run(() => { lock (syncObj) { if (testInst.Wait((s) => Volatile.Read(ref state) > 0, new object(), 60000)) { Interlocked.Exchange(ref result, 1); } else { Interlocked.Exchange(ref result, 2); } } }); Thread.Sleep(100); Assert.AreEqual(0, Volatile.Read(ref result)); lock (syncObj) { testInst.Pulse(); } Thread.Sleep(100); Assert.AreEqual(0, Volatile.Read(ref result)); Interlocked.Increment(ref state); lock (syncObj) { testInst.Pulse(); } TimingAssert.AreEqual(10000, 1, () => Volatile.Read(ref result)); } }
public void TestExceptionPassedFromPredicate() { object syncObj = new object(); lock (syncObj) { using (var testInst = new ConditionVariableOld(syncObj)) { try { object state = new object(); bool result = testInst.Wait((s) => { throw new ApplicationException("test"); }, state, 100000); Assert.IsTrue(result); } catch (Exception) { Assert.AreEqual(0, testInst.WaiterCount); throw; } } } }
public ThreadSafeQueue() { VarFull = new ConditionVariableOld(SharedSyncObj); VarEmpty = new ConditionVariableOld(SharedSyncObj); }