diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIMarsConnection.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIMarsConnection.cs index 90bf83dacc..f929a1ba32 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIMarsConnection.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIMarsConnection.cs @@ -14,50 +14,53 @@ namespace Microsoft.Data.SqlClient.SNI /// internal class SNIMarsConnection { - private const string s_className = nameof(SNIMarsConnection); - - private readonly Guid _connectionId = Guid.NewGuid(); - private readonly Dictionary _sessions = new Dictionary(); - private readonly byte[] _headerBytes = new byte[SNISMUXHeader.HEADER_LENGTH]; - private readonly SNISMUXHeader _currentHeader = new SNISMUXHeader(); + private readonly Guid _connectionId; + private readonly Dictionary _sessions; + private readonly byte[] _headerBytes; + private readonly SNISMUXHeader _currentHeader; + private readonly object _sync; private SNIHandle _lowerHandle; - private ushort _nextSessionId = 0; - private int _currentHeaderByteCount = 0; - private int _dataBytesLeft = 0; + private ushort _nextSessionId; + private int _currentHeaderByteCount; + private int _dataBytesLeft; private SNIPacket _currentPacket; /// /// Connection ID /// - public Guid ConnectionId - { - get - { - return _connectionId; - } - } + public Guid ConnectionId => _connectionId; public int ProtocolVersion => _lowerHandle.ProtocolVersion; + internal object DemuxerSync => _sync; + /// /// Constructor /// /// Lower handle public SNIMarsConnection(SNIHandle lowerHandle) { + _sync = new object(); + _connectionId = Guid.NewGuid(); + _sessions = new Dictionary(); + _headerBytes = new byte[SNISMUXHeader.HEADER_LENGTH]; + _currentHeader = new SNISMUXHeader(); + _nextSessionId = 0; + _currentHeaderByteCount = 0; + _dataBytesLeft = 0; _lowerHandle = lowerHandle; - SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "Created MARS Session Id {0}", args0: ConnectionId); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNIMarsConnection), EventType.INFO, "Created MARS Session Id {0}", args0: ConnectionId); _lowerHandle.SetAsyncCallbacks(HandleReceiveComplete, HandleSendComplete); } public SNIMarsHandle CreateMarsSession(object callbackObject, bool async) { - lock (this) + lock (DemuxerSync) { ushort sessionId = _nextSessionId++; SNIMarsHandle handle = new SNIMarsHandle(this, sessionId, callbackObject, async); _sessions.Add(sessionId, handle); - SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "MARS Session Id {0}, SNI MARS Handle Id {1}, created new MARS Session {2}", args0: ConnectionId, args1: handle?.ConnectionId, args2: sessionId); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNIMarsConnection), EventType.INFO, "MARS Session Id {0}, SNI MARS Handle Id {1}, created new MARS Session {2}", args0: ConnectionId, args1: handle?.ConnectionId, args2: sessionId); return handle; } } @@ -68,23 +71,18 @@ public SNIMarsHandle CreateMarsSession(object callbackObject, bool async) /// public uint StartReceive() { - long scopeID = SqlClientEventSource.Log.TrySNIScopeEnterEvent(s_className); - try + using (TrySNIEventScope.Create(nameof(SNIMarsConnection))) { SNIPacket packet = null; if (ReceiveAsync(ref packet) == TdsEnums.SNI_SUCCESS_IO_PENDING) { - SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "MARS Session Id {0}, Success IO pending.", args0: ConnectionId); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNIMarsConnection), EventType.INFO, "MARS Session Id {0}, Success IO pending.", args0: ConnectionId); return TdsEnums.SNI_SUCCESS_IO_PENDING; } - SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.ERR, "MARS Session Id {0}, Connection not usable.", args0: ConnectionId); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNIMarsConnection), EventType.ERR, "MARS Session Id {0}, Connection not usable.", args0: ConnectionId); return SNICommon.ReportSNIError(SNIProviders.SMUX_PROV, 0, SNICommon.ConnNotUsableError, Strings.SNI_ERROR_19); } - finally - { - SqlClientEventSource.Log.TrySNIScopeLeaveEvent(scopeID); - } } /// @@ -94,18 +92,13 @@ public uint StartReceive() /// SNI error code public uint Send(SNIPacket packet) { - long scopeID = SqlClientEventSource.Log.TrySNIScopeEnterEvent(s_className); - try + using (TrySNIEventScope.Create(nameof(SNIMarsConnection))) { - lock (this) + lock (DemuxerSync) { return _lowerHandle.Send(packet); } } - finally - { - SqlClientEventSource.Log.TrySNIScopeLeaveEvent(scopeID); - } } /// @@ -115,18 +108,13 @@ public uint Send(SNIPacket packet) /// SNI error code public uint SendAsync(SNIPacket packet) { - long scopeID = SqlClientEventSource.Log.TrySNIScopeEnterEvent(s_className); - try + using (TrySNIEventScope.Create(nameof(SNIMarsConnection))) { - lock (this) + lock (DemuxerSync) { return _lowerHandle.SendAsync(packet); } } - finally - { - SqlClientEventSource.Log.TrySNIScopeLeaveEvent(scopeID); - } } /// @@ -136,31 +124,26 @@ public uint SendAsync(SNIPacket packet) /// SNI error code public uint ReceiveAsync(ref SNIPacket packet) { - long scopeID = SqlClientEventSource.Log.TrySNIScopeEnterEvent(s_className); - try + using (TrySNIEventScope.Create(nameof(SNIMarsConnection))) { if (packet != null) { ReturnPacket(packet); #if DEBUG - SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "MARS Session Id {0}, Packet {1} returned", args0: ConnectionId, args1: packet?._id); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNIMarsConnection), EventType.INFO, "MARS Session Id {0}, Packet {1} returned", args0: ConnectionId, args1: packet?._id); #endif packet = null; } - lock (this) + lock (DemuxerSync) { var response = _lowerHandle.ReceiveAsync(ref packet); #if DEBUG - SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "MARS Session Id {0}, Received new packet {1}", args0: ConnectionId, args1: packet?._id); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNIMarsConnection), EventType.INFO, "MARS Session Id {0}, Received new packet {1}", args0: ConnectionId, args1: packet?._id); #endif return response; } } - finally - { - SqlClientEventSource.Log.TrySNIScopeLeaveEvent(scopeID); - } } /// @@ -169,18 +152,13 @@ public uint ReceiveAsync(ref SNIPacket packet) /// SNI error status public uint CheckConnection() { - long scopeID = SqlClientEventSource.Log.TrySNIScopeEnterEvent(s_className); - try + using (TrySNIEventScope.Create(nameof(SNIMarsConnection))) { - lock (this) + lock (DemuxerSync) { return _lowerHandle.CheckConnection(); } } - finally - { - SqlClientEventSource.Log.TrySNIScopeLeaveEvent(scopeID); - } } /// @@ -195,11 +173,11 @@ public void HandleReceiveError(SNIPacket packet) { handle.HandleReceiveError(packet); #if DEBUG - SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.ERR, "MARS Session Id {0}, Packet {1} has Completion Callback", args0: ConnectionId, args1: packet?._id); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNIMarsConnection), EventType.ERR, "MARS Session Id {0}, Packet {1} has Completion Callback", args0: ConnectionId, args1: packet?._id); } else { - SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.ERR, "MARS Session Id {0}, Packet {1} does not have Completion Callback, error not handled.", args0: ConnectionId, args1: packet?._id); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNIMarsConnection), EventType.ERR, "MARS Session Id {0}, Packet {1} does not have Completion Callback, error not handled.", args0: ConnectionId, args1: packet?._id); #endif } } @@ -224,8 +202,7 @@ public void HandleSendComplete(SNIPacket packet, uint sniErrorCode) /// SNI error code public void HandleReceiveComplete(SNIPacket packet, uint sniErrorCode) { - long scopeID = SqlClientEventSource.Log.TrySNIScopeEnterEvent(s_className); - try + using (TrySNIEventScope.Create(nameof(SNIMarsConnection))) { SNISMUXHeader currentHeader = null; SNIPacket currentPacket = null; @@ -233,17 +210,17 @@ public void HandleReceiveComplete(SNIPacket packet, uint sniErrorCode) if (sniErrorCode != TdsEnums.SNI_SUCCESS) { - lock (this) + lock (DemuxerSync) { HandleReceiveError(packet); - SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.ERR, "MARS Session Id {0}, Handled receive error code: {1}", args0: _lowerHandle?.ConnectionId, args1: sniErrorCode); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNIMarsConnection), EventType.ERR, "MARS Session Id {0}, Handled receive error code: {1}", args0: _lowerHandle?.ConnectionId, args1: sniErrorCode); return; } } while (true) { - lock (this) + lock (DemuxerSync) { if (_currentHeaderByteCount != SNISMUXHeader.HEADER_LENGTH) { @@ -259,7 +236,7 @@ public void HandleReceiveComplete(SNIPacket packet, uint sniErrorCode) if (bytesTaken == 0) { sniErrorCode = ReceiveAsync(ref packet); - SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "MARS Session Id {0}, Non-SMUX Header SNI Packet received with code {1}", args0: ConnectionId, args1: sniErrorCode); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNIMarsConnection), EventType.INFO, "MARS Session Id {0}, Non-SMUX Header SNI Packet received with code {1}", args0: ConnectionId, args1: sniErrorCode); if (sniErrorCode == TdsEnums.SNI_SUCCESS_IO_PENDING) { @@ -267,7 +244,7 @@ public void HandleReceiveComplete(SNIPacket packet, uint sniErrorCode) } HandleReceiveError(packet); - SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.ERR, "MARS Session Id {0}, Handled receive error code: {1}", args0: _lowerHandle?.ConnectionId, args1: sniErrorCode); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNIMarsConnection), EventType.ERR, "MARS Session Id {0}, Handled receive error code: {1}", args0: _lowerHandle?.ConnectionId, args1: sniErrorCode); return; } } @@ -276,7 +253,7 @@ public void HandleReceiveComplete(SNIPacket packet, uint sniErrorCode) _dataBytesLeft = (int)_currentHeader.length; _currentPacket = _lowerHandle.RentPacket(headerSize: 0, dataSize: (int)_currentHeader.length); #if DEBUG - SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "MARS Session Id {0}, _dataBytesLeft {1}, _currentPacket {2}, Reading data of length: _currentHeader.length {3}", args0: _lowerHandle?.ConnectionId, args1: _dataBytesLeft, args2: currentPacket?._id, args3: _currentHeader?.length); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNIMarsConnection), EventType.INFO, "MARS Session Id {0}, _dataBytesLeft {1}, _currentPacket {2}, Reading data of length: _currentHeader.length {3}", args0: _lowerHandle?.ConnectionId, args1: _dataBytesLeft, args2: currentPacket?._id, args3: _currentHeader?.length); #endif } @@ -293,7 +270,7 @@ public void HandleReceiveComplete(SNIPacket packet, uint sniErrorCode) if (_dataBytesLeft > 0) { sniErrorCode = ReceiveAsync(ref packet); - SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "MARS Session Id {0}, SMUX DATA Header SNI Packet received with code {1}, _dataBytesLeft {2}", args0: ConnectionId, args1: sniErrorCode, args2: _dataBytesLeft); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNIMarsConnection), EventType.INFO, "MARS Session Id {0}, SMUX DATA Header SNI Packet received with code {1}, _dataBytesLeft {2}", args0: ConnectionId, args1: sniErrorCode, args2: _dataBytesLeft); if (sniErrorCode == TdsEnums.SNI_SUCCESS_IO_PENDING) { @@ -301,7 +278,7 @@ public void HandleReceiveComplete(SNIPacket packet, uint sniErrorCode) } HandleReceiveError(packet); - SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.ERR, "MARS Session Id {0}, Handled receive error code: {1}", args0: _lowerHandle?.ConnectionId, args1: sniErrorCode); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNIMarsConnection), EventType.ERR, "MARS Session Id {0}, Handled receive error code: {1}", args0: _lowerHandle?.ConnectionId, args1: sniErrorCode); return; } } @@ -313,7 +290,7 @@ public void HandleReceiveComplete(SNIPacket packet, uint sniErrorCode) { SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.SMUX_PROV, 0, SNICommon.InvalidParameterError, Strings.SNI_ERROR_5); HandleReceiveError(packet); - SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.ERR, "Current Header Session Id {0} not found, MARS Session Id {1} will be destroyed, New SNI error created: {2}", args0: _currentHeader?.sessionId, args1: _lowerHandle?.ConnectionId, args2: sniErrorCode); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNIMarsConnection), EventType.ERR, "Current Header Session Id {0} not found, MARS Session Id {1} will be destroyed, New SNI error created: {2}", args0: _currentHeader?.sessionId, args1: _lowerHandle?.ConnectionId, args2: sniErrorCode); _lowerHandle.Dispose(); _lowerHandle = null; return; @@ -322,19 +299,19 @@ public void HandleReceiveComplete(SNIPacket packet, uint sniErrorCode) if (_currentHeader.flags == (byte)SNISMUXFlags.SMUX_FIN) { _sessions.Remove(_currentHeader.sessionId); - SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "SMUX_FIN | MARS Session Id {0}, SMUX_FIN flag received, Current Header Session Id {1} removed", args0: _lowerHandle?.ConnectionId, args1: _currentHeader?.sessionId); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNIMarsConnection), EventType.INFO, "SMUX_FIN | MARS Session Id {0}, SMUX_FIN flag received, Current Header Session Id {1} removed", args0: _lowerHandle?.ConnectionId, args1: _currentHeader?.sessionId); } else { currentSession = _sessions[_currentHeader.sessionId]; - SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "MARS Session Id {0}, Current Session assigned to Session Id {1}", args0: _lowerHandle?.ConnectionId, args1: _currentHeader?.sessionId); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNIMarsConnection), EventType.INFO, "MARS Session Id {0}, Current Session assigned to Session Id {1}", args0: _lowerHandle?.ConnectionId, args1: _currentHeader?.sessionId); } } if (currentHeader.flags == (byte)SNISMUXFlags.SMUX_DATA) { currentSession.HandleReceiveComplete(currentPacket, currentHeader); - SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "SMUX_DATA | MARS Session Id {0}, Current Session {1} completed receiving Data", args0: _lowerHandle?.ConnectionId, args1: _currentHeader?.sessionId); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNIMarsConnection), EventType.INFO, "SMUX_DATA | MARS Session Id {0}, Current Session {1} completed receiving Data", args0: _lowerHandle?.ConnectionId, args1: _currentHeader?.sessionId); } if (_currentHeader.flags == (byte)SNISMUXFlags.SMUX_ACK) @@ -342,23 +319,23 @@ public void HandleReceiveComplete(SNIPacket packet, uint sniErrorCode) try { currentSession.HandleAck(currentHeader.highwater); - SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "SMUX_ACK | MARS Session Id {0}, Current Session {1} handled ack", args0: _lowerHandle?.ConnectionId, args1: _currentHeader?.sessionId); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNIMarsConnection), EventType.INFO, "SMUX_ACK | MARS Session Id {0}, Current Session {1} handled ack", args0: _lowerHandle?.ConnectionId, args1: _currentHeader?.sessionId); } catch (Exception e) { - SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.ERR, "SMUX_ACK | MARS Session Id {0}, Exception occurred: {2}", args0: _currentHeader?.sessionId, args1: e?.Message); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNIMarsConnection), EventType.ERR, "SMUX_ACK | MARS Session Id {0}, Exception occurred: {2}", args0: _currentHeader?.sessionId, args1: e?.Message); SNICommon.ReportSNIError(SNIProviders.SMUX_PROV, SNICommon.InternalExceptionError, e); } #if DEBUG Debug.Assert(_currentPacket == currentPacket, "current and _current are not the same"); - SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "SMUX_ACK | MARS Session Id {0}, Current Packet {1} returned", args0: _lowerHandle?.ConnectionId, args1: currentPacket?._id); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNIMarsConnection), EventType.INFO, "SMUX_ACK | MARS Session Id {0}, Current Packet {1} returned", args0: _lowerHandle?.ConnectionId, args1: currentPacket?._id); #endif ReturnPacket(currentPacket); currentPacket = null; _currentPacket = null; } - lock (this) + lock (DemuxerSync) { if (packet.DataLeft == 0) { @@ -370,16 +347,12 @@ public void HandleReceiveComplete(SNIPacket packet, uint sniErrorCode) } HandleReceiveError(packet); - SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.ERR, "MARS Session Id {0}, packet.DataLeft 0, SNI error {2}", args0: _lowerHandle?.ConnectionId, args1: sniErrorCode); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNIMarsConnection), EventType.ERR, "MARS Session Id {0}, packet.DataLeft 0, SNI error {2}", args0: _lowerHandle?.ConnectionId, args1: sniErrorCode); return; } } } } - finally - { - SqlClientEventSource.Log.TrySNIScopeLeaveEvent(scopeID); - } } /// @@ -387,15 +360,10 @@ public void HandleReceiveComplete(SNIPacket packet, uint sniErrorCode) /// public uint EnableSsl(uint options) { - long scopeID = SqlClientEventSource.Log.TrySNIScopeEnterEvent(s_className); - try + using (TrySNIEventScope.Create(nameof(SNIMarsConnection))) { return _lowerHandle.EnableSsl(options); } - finally - { - SqlClientEventSource.Log.TrySNIScopeLeaveEvent(scopeID); - } } /// @@ -403,15 +371,10 @@ public uint EnableSsl(uint options) /// public void DisableSsl() { - long scopeID = SqlClientEventSource.Log.TrySNIScopeEnterEvent(s_className); - try + using (TrySNIEventScope.Create(nameof(SNIMarsConnection))) { _lowerHandle.DisableSsl(); } - finally - { - SqlClientEventSource.Log.TrySNIScopeLeaveEvent(scopeID); - } } public SNIPacket RentPacket(int headerSize, int dataSize) @@ -430,15 +393,10 @@ public void ReturnPacket(SNIPacket packet) /// public void KillConnection() { - long scopeID = SqlClientEventSource.Log.TrySNIScopeEnterEvent(s_className); - try + using (TrySNIEventScope.Create(nameof(SNIMarsConnection))) { _lowerHandle.KillConnection(); } - finally - { - SqlClientEventSource.Log.TrySNIScopeLeaveEvent(scopeID); - } } #endif }