diff --git a/src/Renci.SshNet/Session.cs b/src/Renci.SshNet/Session.cs index a57d5a1e7..dab919552 100644 --- a/src/Renci.SshNet/Session.cs +++ b/src/Renci.SshNet/Session.cs @@ -1788,9 +1788,17 @@ internal static string ToHex(byte[] bytes) /// when the value of is obtained. To workaround this issue /// we synchronize reads from the . /// + /// + /// We assume the socket is still connected if the read lock cannot be acquired immediately. + /// In this case, we just return without actually waiting to acquire + /// the lock. We don't want to wait for the read lock if another thread already has it because + /// there are cases where the other thread holding the lock can be waiting indefinitely for + /// a socket read operation to complete. + /// /// private bool IsSocketConnected() { +#pragma warning disable S2222 // Locks should be released on all paths lock (_socketDisposeLock) { if (!_socket.IsConnected()) @@ -1798,12 +1806,22 @@ private bool IsSocketConnected() return false; } - lock (_socketReadLock) + if (!Monitor.TryEnter(_socketReadLock)) + { + return true; + } + + try { var connectionClosedOrDataAvailable = _socket.Poll(0, SelectMode.SelectRead); return !(connectionClosedOrDataAvailable && _socket.Available == 0); } + finally + { + Monitor.Exit(_socketReadLock); + } } +#pragma warning restore S2222 // Locks should be released on all paths } ///