129 lines
4.8 KiB
Plaintext
129 lines
4.8 KiB
Plaintext
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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();
|
|
}
|
|
}
|
|
}
|