singrdk/base/Libraries/DebugUtils/ImpatientWatcher.sg

108 lines
3.3 KiB
Plaintext
Raw Normal View History

2008-11-17 18:29:00 -05:00
// ----------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ----------------------------------------------------------------------------
using System;
using System.Threading;
namespace Microsoft.Singularity
{
public class ImpatientWatcher : IDisposable
{
readonly Thread! workerThread;
bool ownerIsDone;
bool workerIsRunning;
string! currentStep;
readonly string! description;
readonly string! dbgprefix;
TimeSpan stepTime;
public void Dispose()
{
bool workerWasRunning;
lock (this) {
ownerIsDone = true;
workerWasRunning = workerIsRunning;
if (workerIsRunning) {
Monitor.Pulse(this);
}
}
if (workerWasRunning)
workerThread.Join();
}
public void NextStep(string! step, int stepTimeMilliseconds)
{
NextStep(step, TimeSpan.FromMilliseconds(stepTimeMilliseconds));
}
public void NextStep(string! step, TimeSpan stepTime)
{
lock (this) {
this.currentStep = step;
this.stepTime = stepTime;
Monitor.Pulse(this);
}
}
[Microsoft.Contracts.NotDelayed]
public ImpatientWatcher(string! description, string! firstStep, int stepTimeMilliseconds)
: this(description, firstStep, TimeSpan.FromMilliseconds(stepTimeMilliseconds))
{
}
[Microsoft.Contracts.NotDelayed]
public ImpatientWatcher(string! description, string! firstStep, TimeSpan stepTime)
{
this.workerThread = new Thread(WorkerRoutine);
this.ownerIsDone = false;
this.workerIsRunning = true;
this.currentStep = firstStep;
this.description = description;
this.stepTime = stepTime;
this.dbgprefix = String.Format("ImpatientWatcher({0}): ", description);
base();
workerThread.Start();
}
private void WorkerRoutine()
{
lock (this) {
for (;;) {
if (ownerIsDone) {
// Dbg("owner is done, exiting");
workerIsRunning = false;
return;
}
string! step = currentStep;
// Dbg("waiting for step '{0}'...", step);
if (Monitor.Wait(this, stepTime)) {
// owner pulsed lock before we gave up
// Dbg("step '{0}' has finished", step);
}
else {
// timeout expired before owner pulsed
Dbg("step '{0}' has timed out, still waiting...", step);
}
}
}
}
void Dbg(string! line)
{
DebugStub.WriteLine(dbgprefix + line);
}
void Dbg(string! format, params object[]! args)
{
Dbg(String.Format(format, args));
}
}
}