singrdk/base/Libraries/Services/ManagementExec.sg

123 lines
4.5 KiB
Plaintext

///////////////////////////////////////////////////////////////////////////////
//
// 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<ManagedServiceContract.Exp:Ready> endpoint;
protected TRef<ThreadTerminationContract.Imp:Start> signal;
public ManagementExec([Claims]ManagedServiceContract.Exp:Start! ep,
IRunnable! service)
{
ep.SendSuccess();
endpoint = new TRef<ManagedServiceContract.Exp:Ready>(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<ThreadTerminationContract.Imp:Start>(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
}