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 c3fbe6b6c4..0132d7df58 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,6 +189,8 @@ public override uint Receive(out SNIPacket packet, int timeout) try { SNIPacket errorPacket; + lock (this) + { packet = null; try { @@ -220,6 +222,7 @@ public override uint Receive(out SNIPacket packet, int timeout) } return TdsEnums.SNI_SUCCESS; } + } finally { SqlClientEventSource.Log.TrySNIScopeLeaveEvent(scopeID); @@ -268,43 +271,40 @@ public override uint Send(SNIPacket packet) bool releaseLock = false; try { - lock (this) + // is the packet is marked out out-of-band (attention packets only) it must be + // sent immediately even if a send of recieve operation is already in progress + // because out of band packets are used to cancel ongoing operations + // so try to take the lock if possible but continue even if it can't be taken + if (packet.IsOutOfBand) + { + Monitor.TryEnter(this, ref releaseLock); + } + else { - // is the packet is marked out out-of-band (attention packets only) it must be - // sent immediately even if a send of recieve operation is already in progress - // because out of band packets are used to cancel ongoing operations - // so try to take the lock if possible but continue even if it can't be taken - if (packet.IsOutOfBand) + Monitor.Enter(this); + releaseLock = true; + } + + // 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 + // interleaved + lock (_sendSync) + { + try { - Monitor.TryEnter(this, ref releaseLock); + packet.WriteToStream(_stream); + return TdsEnums.SNI_SUCCESS; } - else + catch (ObjectDisposedException ode) { - Monitor.Enter(this); - releaseLock = true; + SqlClientEventSource.Log.TrySNITraceEvent(" ObjectDisposedException message = {0}.", ode.Message); + return ReportErrorAndReleasePacket(packet, ode); } - - // 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 - // interleaved - lock (_sendSync) + catch (IOException ioe) { - try - { - packet.WriteToStream(_stream); - return TdsEnums.SNI_SUCCESS; - } - catch (ObjectDisposedException ode) - { - SqlClientEventSource.Log.TrySNITraceEvent(" ObjectDisposedException message = {0}.", ode.Message); - return ReportErrorAndReleasePacket(packet, ode); - } - catch (IOException ioe) - { - SqlClientEventSource.Log.TrySNITraceEvent(" IOException message = {0}.", ioe.Message); - - return ReportErrorAndReleasePacket(packet, ioe); - } + SqlClientEventSource.Log.TrySNITraceEvent(" IOException message = {0}.", ioe.Message); + + return ReportErrorAndReleasePacket(packet, ioe); } } }