119 lines
4.4 KiB
Plaintext
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
|
||
|
}
|