public void WaitDoesNotThrowTheSecondTimeForAGivenThread() { var l = new TrackedLock(Locks, "A"); l.BlockingEnter(); var exc = new Exception[1]; var secondTimeSignal = new AutoResetEvent(false); var waiterThread = new Thread( () => { try { l.BlockingEnter(); l.Exit(); secondTimeSignal.WaitOne(); l.BlockingEnter(); l.Exit(); } catch (Exception e) { exc[0] = e; } } ); waiterThread.Priority = ThreadPriority.Highest; waiterThread.Start(); while ( (l.WaitingThreadCount == 0) && (waiterThread.ThreadState != ThreadState.Stopped) && (waiterThread.ThreadState != ThreadState.Aborted) ) { Thread.Sleep(1); } l.Exit(); l.BlockingEnter(); secondTimeSignal.Set(); while ( (l.WaitingThreadCount == 0) && (waiterThread.ThreadState != ThreadState.Stopped) && (waiterThread.ThreadState != ThreadState.Aborted) ) { Thread.Sleep(1); } l.Exit(); waiterThread.Join(); if (exc[0] != null) { throw new Exception("Worker thread failed", exc[0]); } }
public void WaitThrowsIfSimpleDeadlockWouldHaveOccurred() { var lA = new TrackedLock(Locks, "A"); var lB = new TrackedLock(Locks, "B"); lA.BlockingEnter(); var threadStartedSignal = new AutoResetEvent(false); var bOwnerThread = new Thread( () => { lB.BlockingEnter(); threadStartedSignal.Set(); lA.BlockingEnter(); } ); bOwnerThread.Priority = ThreadPriority.Highest; bOwnerThread.Name = "B Owner"; bOwnerThread.Start(); threadStartedSignal.WaitOne(); while (lA.WaitingThreadCount == 0) { Thread.Sleep(1); } Assert.Throws <DeadlockAvertedException>(() => lB.BlockingEnter()); lA.Exit(); bOwnerThread.Join(); }
public void AcquireAndRelease() { var l = new TrackedLock(Locks, "A"); Assert.IsTrue(l.TryEnter().Success); Assert.IsTrue(l.IsHeld); l.Exit(); Assert.IsFalse(l.IsHeld); }
public void DisposeLockCollection() { var l = new TrackedLock(Locks, "A"); Assert.IsTrue(l.TryEnter().Success); Assert.IsTrue(l.IsHeld); Locks.Dispose(); Assert.IsTrue(l.IsHeld); Assert.IsFalse(l.IsDisposed); }
public void WaitThrowsIfAlreadyHeld() { var l = new TrackedLock(Locks, "A"); l.BlockingEnter(); Assert.Throws <LockAlreadyHeldException>(() => l.BlockingEnter()); l.Exit(); }
public void DisposeLock() { var l = new TrackedLock(Locks, "A"); Assert.IsTrue(l.TryEnter()); Assert.IsTrue(l.IsHeld); l.Dispose(); Assert.IsFalse(l.IsHeld); Assert.IsTrue(l.IsDisposed); }
public void AcquireOnSameThreadFails() { var l = new TrackedLock(Locks, "A"); Assert.IsTrue(l.TryEnter().Success); Thread previousOwner; Assert.IsFalse(l.TryEnter(out previousOwner).Success); Assert.AreEqual(Thread.CurrentThread, previousOwner); Assert.AreEqual(l.TryEnter().FailureReason, TrackedLockFailureReason.HeldByCurrentThread); }
public void HeldLockTracking() { var l = new TrackedLock(Locks, "A"); Assert.IsTrue(l.TryEnter().Success); Assert.AreEqual(Thread.CurrentThread, l.HeldBy); l.Exit(); Assert.AreEqual(null, l.HeldBy); }
public void WaitBlocksUntilReleased() { var log = new List <string>(); var l = new TrackedLock(Locks, "A"); lock (log) log.Add("Main+TryEnter"); Assert.IsTrue(l.TryEnter().Success); lock (log) log.Add("Main-TryEnter"); var threadStartedSignal = new AutoResetEvent(false); var waiterThread = new Thread( () => { threadStartedSignal.Set(); lock (log) log.Add("Waiter+Enter"); l.BlockingEnter(); lock (log) log.Add("Waiter-Enter"); l.Exit(); } ); waiterThread.Priority = ThreadPriority.Highest; waiterThread.Name = "Waiter"; waiterThread.Start(); threadStartedSignal.WaitOne(); // FIXME: There's a race here since WaitingThreadCount actually increases // slightly before the thread begins waiting. Bleh. while (l.WaitingThreadCount == 0) { Thread.Sleep(1); } lock (log) log.Add("Main+Exit"); l.Exit(); lock (log) log.Add("Main-Exit"); waiterThread.Join(); Assert.Less(log.IndexOf("Waiter+Enter"), log.IndexOf("Main+Exit")); Assert.Greater(log.IndexOf("Waiter-Enter"), log.IndexOf("Main-Exit")); }
public void RecursiveAcquireOnSameThreadWorks() { var l = new TrackedLock(Locks, "A"); Assert.IsTrue(l.TryEnter().Success); Assert.AreEqual(0, l.RecursionDepth); Assert.IsTrue(l.TryEnter(recursive: true).Success); Assert.AreEqual(1, l.RecursionDepth); l.Exit(); Assert.IsTrue(l.IsHeld); Assert.AreEqual(0, l.RecursionDepth); l.Exit(); Assert.IsFalse(l.IsHeld); }
public void AcquireOnOtherThreadFails() { var l = new TrackedLock(Locks, "A"); Assert.IsTrue(l.TryEnter().Success); Assert.AreEqual(Thread.CurrentThread, RunOnThread( () => { Thread previousOwner; if (l.TryEnter(out previousOwner).Success) { return(null); } else { return(previousOwner); } } )); }
public Entry(QualifiedMemberIdentifier identifier, TrackedLockCollection lockCollection) { Identifier = identifier; StaticAnalysisDataLock = new TrackedLock(lockCollection, () => String.Format("{0}", this.Identifier.ToString())); }