internal override PacketHandle GetResetWritePacket(int dataSize) { SNIHandle handle = Handle; SNIPacket packet = handle.RentPacket(headerSize: handle.ReserveHeaderSize, dataSize: dataSize); #if DEBUG Debug.Assert(packet.IsActive, "packet is not active, a serious pooling error may have occured"); #endif Debug.Assert(packet.ReservedHeaderSize == handle.ReserveHeaderSize, "failed to reserve header"); return(PacketHandle.FromManagedPacket(packet)); }
internal override PacketHandle ReadSyncOverAsync(int timeoutRemaining, out uint error) { SNIHandle handle = Handle; if (handle == null) { throw ADP.ClosedConnectionError(); } error = SNIProxy.Singleton.ReadSyncOverAsync(handle, out SNIPacket packet, timeoutRemaining); return(PacketHandle.FromManagedPacket(packet)); }
internal override PacketHandle GetResetWritePacket() { if (_sniPacket != null) { _sniPacket.Reset(); } else { lock (_writePacketLockObject) { _sniPacket = _writePacketCache.Take(Handle); } } return(PacketHandle.FromManagedPacket(_sniPacket)); }
internal override PacketHandle ReadSyncOverAsync(int timeoutRemaining, out uint error) { SNIHandle handle = Handle; if (handle == null) { throw ADP.ClosedConnectionError(); } error = SNIProxy.GetInstance().ReadSyncOverAsync(handle, out SNIPacket packet, timeoutRemaining); SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.ReadSyncOverAsync | Info | State Object Id {0}, Session Id {1}", _objectID, _sessionHandle?.ConnectionId); #if DEBUG SqlClientEventSource.Log.TryAdvancedTraceEvent("TdsParserStateObjectManaged.ReadSyncOverAsync | TRC | State Object Id {0}, Session Id {1}, Packet {2} received, Packet owner Id {3}, Packet dataLeft {4}", _objectID, _sessionHandle?.ConnectionId, packet?._id, packet?._owner.ConnectionId, packet?.DataLeft); #endif return(PacketHandle.FromManagedPacket(packet)); }
/// <summary> /// Handle send completion /// </summary> /// <param name="packet">SNI packet</param> /// <param name="sniErrorCode">SNI error code</param> public void HandleSendComplete(SNIPacket packet, uint sniErrorCode) { using (TrySNIEventScope.Create(nameof(SNIMarsHandle))) { lock (this) { Debug.Assert(_callbackObject != null); ((TdsParserStateObject)_callbackObject).WriteAsyncCallback(PacketHandle.FromManagedPacket(packet), sniErrorCode); } _connection.ReturnPacket(packet); #if DEBUG SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNIMarsHandle), EventType.INFO, "MARS Session Id {0}, Returned Packet: {1}", args0: ConnectionId, args1: packet?._id); #endif } }
internal void WriteAsyncCallback(SNIPacket packet, uint sniError) { SNIHandle sessionHandle = _sessionHandle; if (sessionHandle != null) { WriteAsyncCallback(IntPtr.Zero, PacketHandle.FromManagedPacket(packet), sniError); sessionHandle?.ReturnPacket(packet); } else { // clear the packet and drop it to GC because we no longer know how to return it to the correct owner // this can only happen if a packet is in-flight when the _sessionHandle is cleared packet.Release(); } }
/// <summary> /// Handle receive completion /// </summary> /// <param name="packet">SNI packet</param> /// <param name="header">SMUX header</param> public void HandleReceiveComplete(SNIPacket packet, SNISMUXHeader header) { long scopeID = SqlClientEventSource.Log.TrySNIScopeEnterEvent(s_className); try { lock (this) { if (_sendHighwater != header.highwater) { SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "MARS Session Id {0}, header.highwater {1}, _sendHighwater {2}, Handle Ack with header.highwater", args0: ConnectionId, args1: header?.highwater, args2: _sendHighwater); HandleAck(header.highwater); } lock (_receivedPacketQueue) { if (_asyncReceives == 0) { _receivedPacketQueue.Enqueue(packet); _packetEvent.Set(); SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "MARS Session Id {0}, _sequenceNumber {1}, _sendHighwater {2}, _receivedPacketQueue count {3}, packet event set", args0: ConnectionId, args1: _sequenceNumber, args2: _sendHighwater, args3: _receivedPacketQueue?.Count); return; } _asyncReceives--; Debug.Assert(_callbackObject != null); SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "MARS Session Id {0}, _sequenceNumber {1}, _sendHighwater {2}, _asyncReceives {3}", args0: ConnectionId, args1: _sequenceNumber, args2: _sendHighwater, args3: _asyncReceives); ((TdsParserStateObject)_callbackObject).ReadAsyncCallback(PacketHandle.FromManagedPacket(packet), 0); } _connection.ReturnPacket(packet); } lock (this) { _receiveHighwater++; } SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "MARS Session Id {0}, _asyncReceives {1}, _receiveHighwater {2}, _sendHighwater {3}, _receiveHighwaterLastAck {4}", args0: ConnectionId, args1: _asyncReceives, args2: _receiveHighwater, args3: _sendHighwater, args4: _receiveHighwaterLastAck); SendAckIfNecessary(); } finally { SqlClientEventSource.Log.TrySNIScopeLeaveEvent(scopeID); } }
/// <summary> /// Handle receive error /// </summary> public void HandleReceiveError(SNIPacket packet) { using (TrySNIEventScope.Create(nameof(SNIMarsHandle))) { // SNIMarsHandle should only receive calls to this function from the SNIMarsConnection aggregator class // which should handle ownership of the packet because the individual mars handles are not aware of // each other and cannot know if they are the last one in the list and that it is safe to return the packet lock (_receivedPacketQueue) { _connectionError = SNILoadHandle.SingletonInstance.LastError; SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNIMarsHandle), EventType.ERR, "MARS Session Id {0}, _connectionError to be handled: {1}", args0: ConnectionId, args1: _connectionError); _packetEvent.Set(); } ((TdsParserStateObject)_callbackObject).ReadAsyncCallback(PacketHandle.FromManagedPacket(packet), 1); } }
/// <summary> /// Handle send completion /// </summary> /// <param name="packet">SNI packet</param> /// <param name="sniErrorCode">SNI error code</param> public void HandleSendComplete(SNIPacket packet, uint sniErrorCode) { long scopeID = SqlClientEventSource.Log.SNIScopeEnterEvent("<sc.SNI.SNIMarsHandle.HandleSendComplete |SNI|INFO|SCOPE>"); try { lock (this) { Debug.Assert(_callbackObject != null); ((TdsParserStateObject)_callbackObject).WriteAsyncCallback(PacketHandle.FromManagedPacket(packet), sniErrorCode); } } finally { SqlClientEventSource.Log.SNIScopeLeaveEvent(scopeID); } }
/// <summary> /// Handle receive completion /// </summary> /// <param name="packet">SNI packet</param> /// <param name="header">SMUX header</param> public void HandleReceiveComplete(SNIPacket packet, SNISMUXHeader header) { long scopeID = SqlClientEventSource.Log.SNIScopeEnterEvent("<sc.SNI.SNIMarsHandle.HandleReceiveComplete |SNI|INFO|SCOPE>"); try { lock (this) { if (_sendHighwater != header.highwater) { HandleAck(header.highwater); } lock (_receivedPacketQueue) { if (_asyncReceives == 0) { _receivedPacketQueue.Enqueue(packet); _packetEvent.Set(); return; } _asyncReceives--; Debug.Assert(_callbackObject != null); ((TdsParserStateObject)_callbackObject).ReadAsyncCallback(PacketHandle.FromManagedPacket(packet), 0); } _connection.ReturnPacket(packet); } lock (this) { _receiveHighwater++; } SendAckIfNecessary(); } finally { SqlClientEventSource.Log.SNIScopeLeaveEvent(scopeID); } }
/// <summary> /// Handle receive error /// </summary> public void HandleReceiveError(SNIPacket packet) { long scopeID = SqlClientEventSource.Log.SNIScopeEnterEvent("<sc.SNI.SNIMarsHandle.HandleReceiveError |SNI|INFO|SCOPE>"); try { lock (_receivedPacketQueue) { _connectionError = SNILoadHandle.SingletonInstance.LastError; _packetEvent.Set(); } ((TdsParserStateObject)_callbackObject).ReadAsyncCallback(PacketHandle.FromManagedPacket(packet), 1); } finally { SqlClientEventSource.Log.SNIScopeLeaveEvent(scopeID); } }
internal void ReadAsyncCallback(SNIPacket packet, uint error) { SNIHandle sessionHandle = _sessionHandle; if (sessionHandle != null) { ReadAsyncCallback(IntPtr.Zero, PacketHandle.FromManagedPacket(packet), error); SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.ReadAsyncCallback | Info | State Object Id {0}, Session Id {1}, Error code returned {2}", _objectID, _sessionHandle?.ConnectionId, error); #if DEBUG SqlClientEventSource.Log.TryAdvancedTraceEvent("TdsParserStateObjectManaged.ReadAsyncCallback | TRC | State Object Id {0}, Session Id {1}, Packet Id = {2}, Error code returned {3}", _objectID, _sessionHandle?.ConnectionId, packet?._id, error); #endif sessionHandle?.ReturnPacket(packet); } else { // clear the packet and drop it to GC because we no longer know how to return it to the correct owner // this can only happen if a packet is in-flight when the _sessionHandle is cleared packet.Release(); } }
/// <summary> /// Handle receive completion /// </summary> /// <param name="packet">SNI packet</param> /// <param name="header">SMUX header</param> public void HandleReceiveComplete(SNIPacket packet, SNISMUXHeader header) { Debug.Assert(_connection != null && Monitor.IsEntered(_connection.DemuxerSync), "SNIMarsHandle.HandleRecieveComplete should be called while holding the SNIMarsConnection.DemuxerSync because it can cause deadlocks"); using (TrySNIEventScope.Create(nameof(SNIMarsHandle))) { lock (this) { if (_sendHighwater != header.Highwater) { SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNIMarsHandle), EventType.INFO, "MARS Session Id {0}, header.highwater {1}, _sendHighwater {2}, Handle Ack with header.highwater", args0: ConnectionId, args1: header.Highwater, args2: _sendHighwater); HandleAck(header.Highwater); } lock (_receivedPacketQueue) { if (_asyncReceives == 0) { _receivedPacketQueue.Enqueue(packet); _packetEvent.Set(); SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNIMarsHandle), EventType.INFO, "MARS Session Id {0}, _sequenceNumber {1}, _sendHighwater {2}, _receivedPacketQueue count {3}, packet event set", args0: ConnectionId, args1: _sequenceNumber, args2: _sendHighwater, args3: _receivedPacketQueue?.Count); return; } _asyncReceives--; Debug.Assert(_callbackObject != null); SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNIMarsHandle), EventType.INFO, "MARS Session Id {0}, _sequenceNumber {1}, _sendHighwater {2}, _asyncReceives {3}", args0: ConnectionId, args1: _sequenceNumber, args2: _sendHighwater, args3: _asyncReceives); ((TdsParserStateObject)_callbackObject).ReadAsyncCallback(PacketHandle.FromManagedPacket(packet), 0); } _connection.ReturnPacket(packet); } lock (this) { _receiveHighwater++; } SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNIMarsHandle), EventType.INFO, "MARS Session Id {0}, _asyncReceives {1}, _receiveHighwater {2}, _sendHighwater {3}, _receiveHighwaterLastAck {4}", args0: ConnectionId, args1: _asyncReceives, args2: _receiveHighwater, args3: _sendHighwater, args4: _receiveHighwaterLastAck); SendAckIfNecessary(); } }
/// <summary> /// Handle send completion /// </summary> /// <param name="packet">SNI packet</param> /// <param name="sniErrorCode">SNI error code</param> public void HandleSendComplete(SNIPacket packet, uint sniErrorCode) { long scopeID = SqlClientEventSource.Log.TrySNIScopeEnterEvent(s_className); try { lock (this) { Debug.Assert(_callbackObject != null); ((TdsParserStateObject)_callbackObject).WriteAsyncCallback(PacketHandle.FromManagedPacket(packet), sniErrorCode); } _connection.ReturnPacket(packet); #if DEBUG SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "MARS Session Id {0}, Returned Packet: {1}", args0: ConnectionId, args1: packet?._id); #endif } finally { SqlClientEventSource.Log.TrySNIScopeLeaveEvent(scopeID); } }
/// <summary> /// Handle receive error /// </summary> public void HandleReceiveError(SNIPacket packet) { long scopeID = SqlClientEventSource.Log.SNIScopeEnterEvent("<sc.SNI.SNIMarsHandle.HandleReceiveError |SNI|INFO|SCOPE>"); try { // SNIMarsHandle should only receive calls to this function from the SNIMarsConnection aggregator class // which should handle ownership of the packet because the individual mars handles are not aware of // each other and cannot know if they are the last one in the list and that it is safe to return the packet lock (_receivedPacketQueue) { _connectionError = SNILoadHandle.SingletonInstance.LastError; _packetEvent.Set(); } ((TdsParserStateObject)_callbackObject).ReadAsyncCallback(PacketHandle.FromManagedPacket(packet), 1); } finally { SqlClientEventSource.Log.SNIScopeLeaveEvent(scopeID); } }
internal void WriteAsyncCallback(SNIPacket packet, uint sniError) => WriteAsyncCallback(IntPtr.Zero, PacketHandle.FromManagedPacket(packet), sniError);
internal void ReadAsyncCallback(SNIPacket packet, uint error) => ReadAsyncCallback(IntPtr.Zero, PacketHandle.FromManagedPacket(packet), error);
internal override PacketHandle ReadAsync(SessionHandle handle, out uint error) { error = SNIProxy.Singleton.ReadAsync(handle.ManagedHandle, out SNIPacket packet); return(PacketHandle.FromManagedPacket(packet)); }
internal void WriteAsyncCallback(SNIPacket packet, uint sniError) { WriteAsyncCallback(IntPtr.Zero, PacketHandle.FromManagedPacket(packet), sniError); _sessionHandle.ReturnPacket(packet); }
internal void ReadAsyncCallback(SNIPacket packet, uint error) { ReadAsyncCallback(IntPtr.Zero, PacketHandle.FromManagedPacket(packet), error); _sessionHandle.ReturnPacket(packet); }
internal override PacketHandle ReadAsync(SessionHandle handle, out uint error) { error = SNIProxy.GetInstance().ReadAsync(handle.ManagedHandle, out SNIPacket packet); SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.ReadAsync | Info | State Object Id {0}, Session Id {1}, Packet DataLeft {2}", _objectID, _sessionHandle?.ConnectionId, packet?.DataLeft); return(PacketHandle.FromManagedPacket(packet)); }