Fix race condition in StdioClientTransport on .NET Framework (#996)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
This commit is contained in:
Copilot 2025-11-24 17:42:16 +02:00 • committed by GitHub
commit e6db415940
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -25,6 +25,12 @@ namespace ModelContextProtocol.Client;
/// </remarks> /// </remarks>
public sealed partial class StdioClientTransport : IClientTransport public sealed partial class StdioClientTransport : IClientTransport
{ {
#if !NET
// On .NET Framework, we need to synchronize access to Console.InputEncoding
// to prevent race conditions when multiple transports are created concurrently.
private static readonly object s_consoleEncodingLock = new();
#endif
private readonly StdioClientTransportOptions _options; private readonly StdioClientTransportOptions _options;
private readonly ILoggerFactory? _loggerFactory; private readonly ILoggerFactory? _loggerFactory;
@ -159,15 +165,20 @@ public sealed partial class StdioClientTransport : IClientTransport
#if NET #if NET
processStarted = process.Start(); processStarted = process.Start();
#else #else
Encoding originalInputEncoding = Console.InputEncoding; // IMPORTANT: This must be synchronized to prevent race conditions when multiple
try // transports are created concurrently.
lock (s_consoleEncodingLock)
{ {
Console.InputEncoding = StreamClientSessionTransport.NoBomUtf8Encoding; Encoding originalInputEncoding = Console.InputEncoding;
processStarted = process.Start(); try
} {
finally Console.InputEncoding = StreamClientSessionTransport.NoBomUtf8Encoding;
{ processStarted = process.Start();
Console.InputEncoding = originalInputEncoding; }
finally
{
Console.InputEncoding = originalInputEncoding;
}
} }
#endif #endif