123 lines
4.5 KiB
Plaintext
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
|
|
}
|