Skip to content

Commit 0647e71

Browse files
committed
Fix the race condition between DisposeAsync and ReadMessageAsync.
1 parent 5cae6fb commit 0647e71

File tree

1 file changed

+5
-1
lines changed

1 file changed

+5
-1
lines changed

src/ModelContextProtocol.Core/Client/StdioClientSessionTransport.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,13 @@ public override async Task SendMessageAsync(JsonRpcMessage message, Cancellation
4747
/// <inheritdoc/>
4848
protected override async ValueTask CleanupAsync(Exception? error = null, CancellationToken cancellationToken = default)
4949
{
50-
// Only clean up once.
50+
// Only run the full stdio cleanup once (handler detach, process kill, etc.).
51+
// But always ensure the channel is completed so DisposeAsync's
52+
// "await Completion" doesn't hang when the ReadMessagesAsync path
53+
// is still mid-cleanup (e.g. blocked in WaitForExitAsync).
5154
if (Interlocked.Exchange(ref _cleanedUp, 1) != 0)
5255
{
56+
SetDisconnected(error);
5357
return;
5458
}
5559

0 commit comments

Comments
 (0)