/////////////////////////////////////////////////////////////////////////////// // // 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! counterRef; private TRef signalRef; internal CounterWorker([Claims]CounterContract.Exp:Start! ep, Counter! counter) { counterRef = new TRef(ep); this.counter = counter; } public void Signal([Claims]ThreadTerminationContract.Exp:Start! ep) { signalRef = new TRef(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 }