From fc87182e3381da9565500d8b3864ee36fd28107d Mon Sep 17 00:00:00 2001 From: Radek Zikmund Date: Thu, 15 Oct 2026 12:45:01 +0200 Subject: [PATCH] Swallow ObjectDisposedException when restoring blocking mode after connect async --- .../src/System/Net/Sockets/SafeSocketHandle.Unix.cs | 4 ++-- .../src/System/Net/Sockets/SocketAsyncContext.Unix.cs | 11 +++++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SafeSocketHandle.Unix.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SafeSocketHandle.Unix.cs index 51fe27eea5d17a..52499be150f6a4 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SafeSocketHandle.Unix.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SafeSocketHandle.Unix.cs @@ -147,10 +147,10 @@ internal bool IsNonBlocking internal bool IsUnderlyingHandleBlocking => !AsyncContext.IsHandleNonBlocking; /// - /// Sets the underlying socket to blocking mode. + /// Attempts to set the underlying socket to blocking mode. /// Only sets blocking if the user hasn't explicitly set Blocking = false (i.e., IsNonBlocking is false). /// This is only safe to call when the socket is guaranteed by construction to not be used concurrently - /// with any other operation, such as at the completion of ConnectAsync. + /// with any other I/O operation, such as at the completion of ConnectAsync. Concurrent disposal is allowed. /// internal void SetBlocking() { diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs index 1fc30b9397621e..9b899beb2ead9f 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs @@ -609,9 +609,16 @@ public void SetHandleBlocking() if (_isHandleNonBlocking) { - if (Interop.Sys.Fcntl.SetIsNonBlocking(_socket, 0) == 0) + try { - _isHandleNonBlocking = false; + if (Interop.Sys.Fcntl.SetIsNonBlocking(_socket, 0) == 0) + { + _isHandleNonBlocking = false; + } + } + catch (ObjectDisposedException) + { + // Concurrent disposal is allowed; restoring blocking mode is only an optimization. } } }