singrdk/base/Kernel/Singularity.Channels/ChannelDeliveryImplService.sg

114 lines
4.0 KiB
Plaintext
Raw Normal View History

2008-11-17 18:29:00 -05:00
///////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// File: ChannelDeliveryImplService.sg
// Note: Channel Delivery Implementation Service
//
using System.Threading;
using Microsoft.SingSharp;
using Microsoft.Singularity;
using Microsoft.Singularity.Channels;
using Microsoft.Singularity.Memory;
using Microsoft.Singularity.Io;
using Microsoft.Singularity.Directory;
using Microsoft.Singularity.Drivers;
using System;
namespace Microsoft.Singularity.Channels
{
public class ChannelDeliveryImplService
{
private void Run()
{
// Here is the channel we use to communicate with
// the NameServer
ServiceProviderContract.Imp! nsImp;
ServiceProviderContract.Exp! nsExp;
ServiceProviderContract.NewChannel(out nsImp, out nsExp);
// Here is our NameServer connection over which we
// receive new client channels.
DirectoryServiceContract.Imp epNS = DirectoryService.NewClientEndpoint();
try {
epNS.SendRegister(Bitter.FromString2(ChannelDeliveryContract.ModuleName), nsImp);
switch receive {
case epNS.AckRegister() :
// All is well.
break;
case epNS.NakRegister(ServiceProviderContract.Imp:Start rejectedEP, ErrorCode error) :
// All is very much not well; abort.
DebugStub.Print("Failed to register the Channel Delivery Impl Service.\n");
if (rejectedEP != null) {
delete rejectedEP;
}
delete nsExp;
return;
}
}
finally {
delete epNS;
}
// Here is the set of client channels we service
ESet<ChannelDeliveryContract.Exp:ReadyState> epSet = new ESet<ChannelDeliveryContract.Exp:ReadyState>();
while (true) {
switch receive {
// Requests for new connections
case nsExp.Connect(ServiceContract.Exp:Start! newEp) :
{
// We expect people to give us ChannelDeliveryContract.Exp instances
ChannelDeliveryContract.Exp newDiagEp = newEp as ChannelDeliveryContract.Exp;
if (newDiagEp == null) {
// Invalid contract type. Fail.
nsExp.SendNackConnect(newEp);
}
else {
// Signal ready and start servicing this contract
nsExp.SendAckConnect();
newDiagEp.SendReady();
epSet.Add(newDiagEp);
}
}
break;
case ep.ChannelClosed() in epSet :
{
// Just toss the closed channel
delete ep;
}
break;
case epSet.Empty() && nsExp.ChannelClosed():
{
delete nsExp;
epSet.Dispose();
return;
}
break;
}
}
}
public static void Initialize()
{
ChannelDeliveryImplService service = new ChannelDeliveryImplService();
Thread thread = Thread.CreateThread(null, new ThreadStart(service.Run));
if (thread != null) {
thread.Start();
}
}
}
}