void ExerciseStandardUsage(ISyncLock lockObject, bool throwException) { using (AutoLock.Lock(lockObject)) { Console.WriteLine("Inside autolock block"); if (throwException) { Console.WriteLine("Testing exception thrown in autolock block -- will now throw exception"); throw new IntentionalTestException("Intentional exception thrown inside of an autolock block"); } } InvalidOperationException unlockException = null; Console.WriteLine("Validate that the lock is correctly unlocked after exiting using block"); try { lockObject.Unlock(); } catch (InvalidOperationException e) { unlockException = e; } if (unlockException != null) { Console.WriteLine("Caught expected exception from unlocking an unlocked object"); } else { throw new InvalidOperationException("Failed to get exception in unlocking unlocked object after an autolock was exited"); } }
void VerifyUnlocked(ISyncLock syncLock) { InvalidOperationException tooManyUnlocksException = null; try { syncLock.Unlock(); } catch (InvalidOperationException e) { Console.WriteLine("Caught expected exception after unlocking too many times: {0}: {1}", e.GetType().ToString(), e.Message); tooManyUnlocksException = e; } if (tooManyUnlocksException == null) { throw new InvalidOperationException("Unlock should not have succeeded after being in what should have been an unlocked state"); } }
void TestLockWait(ISyncLock syncLock, TimeSpan waitBeforeCheckingLock, TimeSpan addtionalTimeBeforeRelease, bool waitForUnlock) { TimeSpan expectedWaitTime = new TimeSpan((long)(Math.Min(waitBeforeCheckingLock.Ticks, addtionalTimeBeforeRelease.Ticks))) + new TimeSpan(0,0,3); lockCheckReadyAcquired.Reset(); lockReleaseEvent.Reset(); variationCompleteEvent.Reset(); lockWaitTime = waitBeforeCheckingLock; // +waitBeforeCheckingLock; releaseDelay = addtionalTimeBeforeRelease; lockThread = new Thread(LockThreadFunction); lockThread.Start(syncLock); WaitForLockAcquisition(); // This should expire bool expired = ! syncLock.WaitForLock(new TimeSpan(0,0,0)); if (! expired) { throw new InvalidOperationException("Lock was released before expected, due to either lock defect or race conditions that should be rare"); } // Tell the other thread to release the lock lockReleaseEvent.Set(); DateTime waitStart = DateTime.UtcNow; if (waitForUnlock) { WaitForLockRelease(); } bool acquiredLock = syncLock.WaitForLock(lockWaitTime); DateTime waitEnd = DateTime.UtcNow; variationCompleteEvent.Set(); if (!acquiredLock) { if (waitForUnlock || ( waitBeforeCheckingLock > addtionalTimeBeforeRelease) ) { throw new InvalidOperationException("Unable to acquire lock within the specified timeout"); } else { Console.WriteLine("Wait for lock timed out as expected"); } } else { syncLock.Unlock(); if (waitBeforeCheckingLock < addtionalTimeBeforeRelease) { throw new InvalidOperationException("Wait did not time out as expected"); } else { Console.WriteLine("Wait was satisfied as expected"); } } TimeSpan duration = waitEnd - waitStart; Console.WriteLine("Expected wait time was {0} and actual time was {1}", expectedWaitTime, duration); if (duration > expectedWaitTime) { throw new InvalidOperationException(string.Format("Expected wait time was {0} and actual time was {1}", expectedWaitTime, duration)); } }