Skip to content

Commit 08f9cdb

Browse files
authored
Fix race in TransportBase.SetConnected (#253)
* Fix race in TransportBase.SetConnected - Previously the ChannelWriter could already be completed if multiple threads raced in SetConnected(false) * Fix WriteMessageAsync IsConnected test
1 parent b3a5a82 commit 08f9cdb

File tree

1 file changed

+5
-5
lines changed

1 file changed

+5
-5
lines changed

src/ModelContextProtocol/Protocol/Transport/TransportBase.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public abstract class TransportBase : ITransport
1313
{
1414
private readonly Channel<IJsonRpcMessage> _messageChannel;
1515
private readonly ILogger _logger;
16-
private bool _isConnected;
16+
private int _isConnected;
1717

1818
/// <summary>
1919
/// Initializes a new instance of the <see cref="TransportBase"/> class.
@@ -30,7 +30,7 @@ protected TransportBase(ILoggerFactory? loggerFactory)
3030
}
3131

3232
/// <inheritdoc/>
33-
public bool IsConnected => _isConnected;
33+
public bool IsConnected => _isConnected == 1;
3434

3535
/// <inheritdoc/>
3636
public ChannelReader<IJsonRpcMessage> MessageReader => _messageChannel.Reader;
@@ -48,7 +48,7 @@ protected TransportBase(ILoggerFactory? loggerFactory)
4848
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
4949
protected async Task WriteMessageAsync(IJsonRpcMessage message, CancellationToken cancellationToken = default)
5050
{
51-
if (!_isConnected)
51+
if (!IsConnected)
5252
{
5353
throw new McpTransportException("Transport is not connected");
5454
}
@@ -64,12 +64,12 @@ protected async Task WriteMessageAsync(IJsonRpcMessage message, CancellationToke
6464
/// <param name="isConnected">Whether the transport is connected.</param>
6565
protected void SetConnected(bool isConnected)
6666
{
67-
if (_isConnected == isConnected)
67+
var newIsConnected = isConnected ? 1 : 0;
68+
if (Interlocked.Exchange(ref _isConnected, newIsConnected) == newIsConnected)
6869
{
6970
return;
7071
}
7172

72-
_isConnected = isConnected;
7373
if (!isConnected)
7474
{
7575
_messageChannel.Writer.Complete();

0 commit comments

Comments
 (0)