diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNINpHandle.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNINpHandle.cs index d91d1a08d3..9280bbfc54 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNINpHandle.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNINpHandle.cs @@ -189,39 +189,36 @@ public override uint Receive(out SNIPacket packet, int timeout) try { SNIPacket errorPacket; - lock (this) + packet = null; + try { - packet = null; - try - { - packet = RentPacket(headerSize: 0, dataSize: _bufferSize); - packet.ReadFromStream(_stream); + packet = RentPacket(headerSize: 0, dataSize: _bufferSize); + packet.ReadFromStream(_stream); - if (packet.Length == 0) - { - errorPacket = packet; - packet = null; - var e = new Win32Exception(); - SqlClientEventSource.Log.TrySNITraceEvent(" packet length is 0."); - return ReportErrorAndReleasePacket(errorPacket, (uint)e.NativeErrorCode, 0, e.Message); - } - } - catch (ObjectDisposedException ode) + if (packet.Length == 0) { errorPacket = packet; packet = null; - SqlClientEventSource.Log.TrySNITraceEvent(" ObjectDisposedException message = {0}.", ode.Message); - return ReportErrorAndReleasePacket(errorPacket, ode); + var e = new Win32Exception(); + SqlClientEventSource.Log.TrySNITraceEvent(" packet length is 0."); + return ReportErrorAndReleasePacket(errorPacket, (uint)e.NativeErrorCode, 0, e.Message); } - catch (IOException ioe) - { - errorPacket = packet; - packet = null; - SqlClientEventSource.Log.TrySNITraceEvent(" IOException message = {0}.", ioe.Message); - return ReportErrorAndReleasePacket(errorPacket, ioe); - } - return TdsEnums.SNI_SUCCESS; } + catch (ObjectDisposedException ode) + { + errorPacket = packet; + packet = null; + SqlClientEventSource.Log.TrySNITraceEvent(" ObjectDisposedException message = {0}.", ode.Message); + return ReportErrorAndReleasePacket(errorPacket, ode); + } + catch (IOException ioe) + { + errorPacket = packet; + packet = null; + SqlClientEventSource.Log.TrySNITraceEvent(" IOException message = {0}.", ioe.Message); + return ReportErrorAndReleasePacket(errorPacket, ioe); + } + return TdsEnums.SNI_SUCCESS; } finally { @@ -286,7 +283,7 @@ public override uint Send(SNIPacket packet) } // this lock ensures that two packets are not being written to the transport at the same time - // so that sending a standard and an out-of-band packet are both written atomically no data is + // so that sending a standard and an out-of-band packet are both written atomically no data is // interleaved lock (_sendSync) { diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNITcpHandle.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNITcpHandle.cs index b3393e3752..f919d3cf52 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNITcpHandle.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNITcpHandle.cs @@ -143,7 +143,7 @@ public SNITCPHandle(string serverName, int port, long timerExpire, object callba bool reportError = true; // We will always first try to connect with serverName as before and let the DNS server to resolve the serverName. - // If the DSN resolution fails, we will try with IPs in the DNS cache if existed. We try with IPv4 first and followed by IPv6 if + // If the DSN resolution fails, we will try with IPs in the DNS cache if existed. We try with IPv4 first and followed by IPv6 if // IPv4 fails. The exceptions will be throw to upper level and be handled as before. try { @@ -582,7 +582,7 @@ public override uint Send(SNIPacket packet) } // this lock ensures that two packets are not being written to the transport at the same time - // so that sending a standard and an out-of-band packet are both written atomically no data is + // so that sending a standard and an out-of-band packet are both written atomically no data is // interleaved lock (_sendSync) { @@ -623,67 +623,65 @@ public override uint Send(SNIPacket packet) public override uint Receive(out SNIPacket packet, int timeoutInMilliseconds) { SNIPacket errorPacket; - lock (this) + packet = null; + try { - packet = null; - try + if (timeoutInMilliseconds > 0) { - if (timeoutInMilliseconds > 0) - { - _socket.ReceiveTimeout = timeoutInMilliseconds; - } - else if (timeoutInMilliseconds == -1) - { // SqlCient internally represents infinite timeout by -1, and for TcpClient this is translated to a timeout of 0 - _socket.ReceiveTimeout = 0; - } - else - { - // otherwise it is timeout for 0 or less than -1 - ReportTcpSNIError(0, SNICommon.ConnTimeoutError, string.Empty); - return TdsEnums.SNI_WAIT_TIMEOUT; - } - - packet = RentPacket(headerSize: 0, dataSize: _bufferSize); - packet.ReadFromStream(_stream); - - if (packet.Length == 0) - { - errorPacket = packet; - packet = null; - var e = new Win32Exception(); - return ReportErrorAndReleasePacket(errorPacket, (uint)e.NativeErrorCode, 0, e.Message); - } - - return TdsEnums.SNI_SUCCESS; + _socket.ReceiveTimeout = timeoutInMilliseconds; } - catch (ObjectDisposedException ode) + else if (timeoutInMilliseconds == -1) { - errorPacket = packet; - packet = null; - return ReportErrorAndReleasePacket(errorPacket, ode); + // SqlClient internally represents infinite timeout by -1, and for TcpClient this is translated to a timeout of 0 + _socket.ReceiveTimeout = 0; } - catch (SocketException se) + else { - errorPacket = packet; - packet = null; - return ReportErrorAndReleasePacket(errorPacket, se); + // otherwise it is timeout for 0 or less than -1 + ReportTcpSNIError(0, SNICommon.ConnTimeoutError, string.Empty); + return TdsEnums.SNI_WAIT_TIMEOUT; } - catch (IOException ioe) + + packet = RentPacket(headerSize: 0, dataSize: _bufferSize); + packet.ReadFromStream(_stream); + + if (packet.Length == 0) { errorPacket = packet; packet = null; - uint errorCode = ReportErrorAndReleasePacket(errorPacket, ioe); - if (ioe.InnerException is SocketException socketException && socketException.SocketErrorCode == SocketError.TimedOut) - { - errorCode = TdsEnums.SNI_WAIT_TIMEOUT; - } - - return errorCode; + var e = new Win32Exception(); + return ReportErrorAndReleasePacket(errorPacket, (uint)e.NativeErrorCode, 0, e.Message); } - finally + + return TdsEnums.SNI_SUCCESS; + } + catch (ObjectDisposedException ode) + { + errorPacket = packet; + packet = null; + return ReportErrorAndReleasePacket(errorPacket, ode); + } + catch (SocketException se) + { + errorPacket = packet; + packet = null; + return ReportErrorAndReleasePacket(errorPacket, se); + } + catch (IOException ioe) + { + errorPacket = packet; + packet = null; + uint errorCode = ReportErrorAndReleasePacket(errorPacket, ioe); + if (ioe.InnerException is SocketException socketException && socketException.SocketErrorCode == SocketError.TimedOut) { - _socket.ReceiveTimeout = 0; + errorCode = TdsEnums.SNI_WAIT_TIMEOUT; } + + return errorCode; + } + finally + { + _socket.ReceiveTimeout = 0; } } @@ -750,15 +748,15 @@ public override uint CheckConnection() { try { - // _socket.Poll method with argument SelectMode.SelectRead returns + // _socket.Poll method with argument SelectMode.SelectRead returns // True : if Listen has been called and a connection is pending, or // True : if data is available for reading, or // True : if the connection has been closed, reset, or terminated, i.e no active connection. // False : otherwise. // _socket.Available property returns the number of bytes of data available to read. // - // Since _socket.Connected alone doesn't guarantee if the connection is still active, we use it in - // combination with _socket.Poll method and _socket.Available == 0 check. When both of them + // Since _socket.Connected alone doesn't guarantee if the connection is still active, we use it in + // combination with _socket.Poll method and _socket.Available == 0 check. When both of them // return true we can safely determine that the connection is no longer active. if (!_socket.Connected || (_socket.Poll(100, SelectMode.SelectRead) && _socket.Available == 0)) {