singrdk/base/Services/Tests/Counter/CounterWorker.sg

119 lines
4.4 KiB
Plaintext

///////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// File: Service\Test\Counter\CounterWorker.sg
//
// Note:
//
using System;
using System.Threading;
using Microsoft.SingSharp;
using Microsoft.Singularity;
using Microsoft.Singularity.Channels;
using Microsoft.Singularity.Directory;
using Microsoft.Singularity.Resiliency;
using Microsoft.Singularity.ServiceManager;
using Microsoft.Singularity.Services;
namespace Microsoft.Singularity.Services.Counter
{
internal sealed class CounterWorker : IRunnable
{
private Counter! counter;
private TRef<CounterContract.Exp:Start>! counterRef;
private TRef<ThreadTerminationContract.Exp:Start> signalRef;
internal CounterWorker([Claims]CounterContract.Exp:Start! ep,
Counter! counter)
{
counterRef = new TRef<CounterContract.Exp:Start>(ep);
this.counter = counter;
}
public void Signal([Claims]ThreadTerminationContract.Exp:Start! ep)
{
signalRef = new TRef<ThreadTerminationContract.Exp:Start>(ep);
}
public void Run()
{
CounterContract.Exp:Start! ep;
ThreadTerminationContract.Exp:Start! sig;
bool next = false;
assert signalRef != null;
ep = counterRef.Acquire();
sig = signalRef.Acquire();
ep.SendSuccess();
for (;;) {
switch receive {
case ep.Increment():
ep.SendAckIncrement(counter.Count);
counter.Increment();
break;
case ep.BeginCount():
do {
if (counter.Count < Int32.MaxValue) {
// HI: fault injection
int now = DateTime.UtcNow.Second;
if (now == 0 || now == 20 || now == 40) {
DebugStub.Print("%-) Fault Injection "
+ now);
Thread.Sleep(1000);
goto exit;
}
// HI: fault injection end
DebugStub.Print("Counter: Send "
+ counter.Count + "\n");
ep.SendCurrent(counter.Count);
}
else {
DebugStub.Print("Counter exceeds max\n");
ep.SendTerminated();
break;
}
switch receive {
case ep.RecvNext():
next = true;
counter.Increment();
break;
case ep.RecvEnd():
next = false;
break;
case ep.ChannelClosed():
DebugStub.Print("Counter: " +
"Channel is closed.\n");
goto exit;
break;
case sig.Stop():
sig.SendAckStop();
goto exit;
break;
}
} while (next);
break;
case ep.ChannelClosed():
goto exit;
break;
case sig.Stop():
sig.SendAckStop();
goto exit;
break;
case sig.ChannelClosed():
goto exit;
}
}
exit:
delete ep;
signalRef.Release(sig);
return;
}
} // class
}