/////////////////////////////////////////////////////////////////////////////// // // Microsoft Research Singularity // // Copyright (c) Microsoft Corporation. All rights reserved. // // File: Libraries\Resiliency\Proxy.sg // // Note: // using System; using System.Threading; using Microsoft.SingSharp; using Microsoft.Singularity; using Microsoft.Singularity.Channels; using Microsoft.Singularity.Directory; using Microsoft.Singularity.Services; using Microsoft.Singularity.ServiceManager; namespace Microsoft.Singularity.Resiliency { public sealed class ServiceProxy { private Thread serviceThread; private JournaletFactory! factory; private TRef serviceRef; private TRef recoveryRef; private TRef rootDsRef; private TRef myDsRef; private TRef proxyRef; public ServiceProxy(JournaletFactory! factory, [Claims]ManagedServiceContract.Exp:Start! mep, [Claims]ManagedProxyContract.Imp:Start! pep, [Claims]DirectoryServiceContract.Imp:Ready! dep, [Claims]DirectoryServiceContract.Exp:Start! fep, [Claims]ServiceProxyContract.Exp:Start! xep) { this.factory = factory; this.rootDsRef = new TRef(dep); fep.SendSuccess(); this.myDsRef = new TRef(fep); mep.SendSuccess(); this.serviceRef = new TRef(mep); switch receive { case pep.Success(): break; case unsatisfiable: DebugStub.Break(); break; } this.recoveryRef = new TRef(pep); xep.SendSuccess(); this.proxyRef = new TRef(xep); } public void Start() { if (serviceThread == null) { serviceThread = new Thread(new ThreadStart(Run)); } serviceThread.Start(); } public void Run() { Thread thread = null; DirectoryServiceProxy dsProxy; ManagedServiceContract.Exp:Ready! manager; ThreadTerminationContract.Imp! imp; ThreadTerminationContract.Exp! exp; DebugStub.Print("-- Start proxy\n"); dsProxy = new DirectoryServiceProxy(this, factory, rootDsRef.Acquire(), myDsRef.Acquire(), proxyRef.Acquire()); ThreadTerminationContract.NewChannel(out imp, out exp); dsProxy.Signal(exp); manager = serviceRef.Acquire(); for (;;) { switch receive { case manager.StartService(): { if (thread == null) { thread = new Thread(new ThreadStart(dsProxy.Run)); } thread.Start(); manager.SendAckStartService(); break; } case manager.StopService(): { DebugStub.Print("Px: recv stop service\n"); imp.SendStop(); switch receive { case imp.AckStop(): manager.SendAckStopService(); break; case unsatisfiable: manager.SendBusy(); break; } thread = null; break; } case manager.RestartService(): { manager.SendAckRestartService(); break; } case manager.Knock(): { manager.SendAlive(); break; } case manager.Stop(): { imp.SendStop(); switch receive { case unsatisfiable: break; } manager.SendAckStop(); goto exit; break; } case manager.Restart(): { DebugStub.Break(); manager.SendAckRestart(); break; } } } exit: delete manager; delete recoveryRef.Acquire(); delete imp; } /// /// Asks ServiceManager to recover the corresponding service and /// the initial direct channels to the service. /// internal void RecoverService(out DirectoryServiceContract.Exp:Ready ep, out ServiceProxyContract.Exp:Ready xep) { ManagedProxyContract.Imp:Ready! manager; DebugStub.Print("Px: Enter RecoverService\n"); manager = recoveryRef.Acquire(); #if COMPATIBLE_V1 manager.SendRequestDSRecovery(); switch receive { case manager.AckDSRecovery(proxy): #else manager.SendRequestRecovery(); switch receive { case manager.AckRecovery(directory, proxy): #endif { directory.SendSuccess(); proxy.SendSuccess(); ep = directory; xep = proxy; break; } case unsatisfiable: { ep = null; xep = null; break; } } recoveryRef.Release(manager); DebugStub.Print("Px: Exit RecoverService\n"); } } }