| File: CoordinatorServer.ConnectedClient.cs | Web Access |
| Project: src\msbuild\src\MSBuild.Coordinator\MSBuild.Coordinator.csproj (MSBuild.Coordinator) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Immutable; using System.IO; using System.IO.Pipes; using System.Threading; using Microsoft.Build.Framework.Coordinator; namespace Microsoft.Build.Coordinator; internal sealed partial class CoordinatorServer { /// <summary> /// Tracks an accepted MSBuild client alongside its <see cref="BuildGrant"/>. /// </summary> private sealed class ConnectedClient : IDisposable { private readonly NamedPipeServerStream _pipeStream; private readonly BinaryReader _reader; private readonly BinaryWriter _writer; private int _disposed; /// <summary> /// Gets the unique identifier for this connection, assigned by the client during handshake. /// </summary> public Guid ConnectionId { get; } /// <summary> /// Gets the process ID of the connected MSBuild client. /// </summary> public int ProcessId { get; } /// <summary> /// Gets the capabilities advertised by the client during handshake. /// </summary> public ImmutableArray<string> Capabilities { get; } /// <summary> /// Gets the build grant associated with this client. /// </summary> public BuildGrant Grant { get; } /// <summary> /// Gets a value indicating whether the pipe is still connected to the client. /// </summary> public bool IsConnected => _pipeStream.IsConnected; /// <summary> /// Creates a connected client by taking ownership of a negotiated connection. /// </summary> public ConnectedClient(Connection connection, BuildGrant grant) { (_pipeStream, _reader, _writer) = connection.TransferOwnership(); ConnectionId = connection.Id; ProcessId = connection.ProcessId; Capabilities = connection.ClientCapabilities; Grant = grant; } /// <summary> /// Reads the next client message from this connected client. /// </summary> public ClientMessage ReadClientMessage() => _reader.ReadClientMessage(); /// <summary> /// Writes a server message to this connected client. /// </summary> public void WriteServerMessage(ServerMessage message) => _writer.Write(message); public void Dispose() { if (Interlocked.Exchange(ref _disposed, 1) != 0) { return; } try { _writer.Dispose(); } catch (IOException) { // The pipe may already be broken if the client disconnected. } _reader.Dispose(); _pipeStream.Dispose(); } } }