singrdk/base/Services/NetStack/Channels.Private/UDPExpManager.sg

129 lines
4.8 KiB
Plaintext
Raw Normal View History

2008-03-05 09:52:00 -05:00
///////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// File: UdpExpManager.sg
//
// Note: Provider-side helper for the IP Channel Contract
//
using System.Threading;
using System.Net.IP;
using Microsoft.SingSharp;
using Microsoft.Singularity;
using Microsoft.Singularity.Channels;
using Microsoft.Singularity.Directory;
using NetStack.Contracts;
using NetStack.Runtime;
using System.Collections;
using System;
namespace NetStack.Channels.Private
{
public class UdpExpManager
{
public void Run()
{
// Here is the set of client channels we service
ESet<UdpContract.Exp:ReadyState> epSet = new ESet<UdpContract.Exp:ReadyState>();
// 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. When we become a
// process, this will be present automatically,
// somehow.
DirectoryServiceContract.Imp epNS = DirectoryService.NewClientEndpoint();
try {
epNS.SendRegister(Bitter.FromString2(UdpContract.ModuleName), nsImp);
switch receive {
case epNS.AckRegister() :
// All is well.
break;
case epNS.NakRegister(ServiceProviderContract.Imp:Start rejectedEP, error) :
// All is very much not well; abort.
DebugStub.Print("Failed to register the Udp module.\n");
delete rejectedEP;
delete nsExp;
epSet.Dispose();
return;
break;
}
}
finally {
delete epNS;
}
while(true) {
switch receive {
//
// Don't forget that we're selecting UdpContract endpoints
// from the epSet endpoint-set. In each case that we
// receive a message from one of those endpoints, we
// need to remember to put the endpoint back into epSet
// if we want to keep listening to it.
//
case ep.CreateUdpSession(UdpConnectionContract.Exp:Start! newEP) in epSet :
{
// Move the endpoint to the ReadyState
newEP.SendReady();
// Create a dedicated thread to service this connection
UdpConnectionExpThread udpThread = new UdpConnectionExpThread(newEP);
udpThread.Start();
ep.SendAck();
epSet.Add(ep);
}
break;
case nsExp.Connect(ServiceContract.Exp:Start! newEp) :
{
// We expect people top give us
// UdpContract.Exp instances
// UdpContract.Exp:Start newUdpEp = newEp
// as UdpContract.Exp;
UdpContract.Exp newUdpEp = newEp as UdpContract.Exp;
if (newUdpEp == null) {
// Invalid contract type. Fail.
nsExp.SendNackConnect(newEp);
}
else {
// Signal ready and start
// servicing this contract
nsExp.SendAckConnect();
newUdpEp.SendReady();
epSet.Add(newUdpEp);
}
}
break;
case ep.ChannelClosed() in epSet :
delete ep;
break;
case nsExp.ChannelClosed():
// Exit this thread
delete nsExp;
epSet.Dispose();
return;
}
}
}
public void Start()
{
Thread newThread = new Thread(new ThreadStart(Run));
newThread.Start();
}
}
}