in EnvDTE.Host/ConnectionManager.cs [60:99]
public ProtocolFactory(
Lifetime lifetime,
Func<SocketWire.WireParameters> wireParametersFactory,
IPEndPoint? endpoint = null
)
{
var serverSocket = SocketWire.Server.CreateServerSocket(endpoint);
var serverSocketLifetimeDef = new LifetimeDefinition(lifetime);
serverSocketLifetimeDef.Lifetime.OnTermination(() =>
{
SocketWire.Base.CloseSocket(serverSocket);
});
localPort = ((IPEndPoint) serverSocket.LocalEndPoint).Port;
void Rec()
{
lifetime.TryExecute(() =>
{
var (scheduler, id) = wireParametersFactory();
var s = new SocketWire.Server(lifetime, scheduler, serverSocket, id);
// Create one protocol per server, this way server instances can be reused for multiple client connections
var proto = new Protocol($"{s.Id}-Protocol", new Serializers(), new Identities(IdKind.Server), scheduler, s, lifetime);
// Each server will spawn a thread that will be waiting in serverSocket.Accept method. When lifetime
// termination is invoked, these threads synchronously join the termination thread. Since these Thread.Join
// calls are located deeper in the Lifetime termination stack we have to place this socket termination call
// after each server creation.
lifetime.OnTermination(() => serverSocketLifetimeDef.Terminate());
s.Connected.WhenTrue(lifetime, lt =>
{
connected.AddLifetimed(lt, proto);
Rec();
});
});
}
Rec();
}