/////////////////////////////////////////////////////////////////////////////// // // Microsoft Research Singularity // // Copyright (c) Microsoft Corporation. All rights reserved. // // File: Libraries\Services\ManagementExec.sg // // Note: Managed service provider base template // using System; using System.Threading; using Microsoft.SingSharp; using Microsoft.Singularity; using Microsoft.Singularity.Channels; using Microsoft.Singularity.ServiceManager; using Microsoft.Singularity.Services; namespace Microsoft.Singularity.Services { public class ManagementExec : IRunnable { protected readonly IRunnable! service; protected readonly TRef endpoint; protected TRef signal; public ManagementExec([Claims]ManagedServiceContract.Exp:Start! ep, IRunnable! service) { ep.SendSuccess(); endpoint = new TRef(ep); this.service = service; } public void Signal([Claims]ThreadTerminationContract.Exp:Start! ep) { delete ep; } public void Run() { Thread serviceThread = null; ManagedServiceContract.Exp:Ready! ep; ThreadTerminationContract.Imp:Start! sig; ThreadTerminationContract.Imp! imp; ThreadTerminationContract.Exp! exp; ep = endpoint.Acquire(); for (;;) { // HI: can't fully hoist ep and sig together because there // can be a situation where sig is closed but ep waits for // messages from Service Manager. switch receive { case ep.StartService(): { ThreadTerminationContract.NewChannel(out imp, out exp); signal = new TRef(imp); service.Signal(exp); serviceThread = new Thread(new ThreadStart(service.Run)); serviceThread.Start(); ep.SendAckStartService(); break; } case ep.StopService(): { if (signal != null && serviceThread != null) { sig = signal.Acquire(); try { sig.SendStop(); switch receive { case sig.AckStop(): break; case sig.ChannelClosed(): break; } } catch (Exception) { DebugStub.Print("ManagementExec: " + "already closed\n"); } signal.Release(sig); serviceThread.Join(); } ep.SendAckStopService(); break; } case ep.RestartService(): { ep.SendAckRestartService(); break; } case ep.Knock(): { ep.SendAlive(); break; } case ep.Restart(): { ep.SendAckRestart(); break; } case ep.Stop(): { ep.SendAckStop(); goto exit; break; } case ep.ChannelClosed(): { DebugStub.Print("ManagementExec: Bug? " + "Manager channel closed.\n"); goto exit; break; } } } exit: delete ep; return; } } // class }