private void Pause(int timeoutMS, ILog log)
{
// Ensure only a single thread owns the pause lock.
Monitor.Enter(pauseLock);
try
{
// At this point the current thread has been granted the pauseLock and can start blocking future activities as well as
// wait for any current activities to complete.
lock (fieldsLock)
{
// stop future activities from starting
paused = true;
// Wait for any activities that are currently executing to complete
int freeActivities = (CurrentThreadActivity != null ? 1 : 0);
if (activityCount > freeActivities)
{
// Let other threads know we're interested in knowing when we're idle and wait
activitiesDone = new AutoResetEvent(false);
// Take into account that the lock request may be occuring either from an existing activity
pendingActivities = activityCount - freeActivities;
}
}
// Wait for other request threads to complete
if (activitiesDone != null)
{
log.Write("Waiting for other amnesia activities to complete...");
bool signalReceived = activitiesDone.WaitOne(timeoutMS);
activitiesDone = null;
if(signalReceived)
log.Write("Other amnesia activities completed successfully.");
else
log.Write(string.Format("WARNING: Timeout ({0} milliseconds) reached while waiting for other amnesia activities to complete.", timeoutMS));
}
// Hold the pauseLock open until Resume()
}
catch (Exception)
{
// An unexpected error occurred so release the pauseLock
Resume();
throw;
}
}