internal override void Dispose() { SNIPacket packetHandle = _sniPacket; SNIHandle sessionHandle = _sessionHandle; SNIPacket asyncAttnPacket = _sniAsyncAttnPacket; _sniPacket = null; _sessionHandle = null; _sniAsyncAttnPacket = null; _marsConnection = null; DisposeCounters(); if (null != sessionHandle || null != packetHandle) { packetHandle?.Dispose(); asyncAttnPacket?.Dispose(); if (sessionHandle != null) { sessionHandle.Dispose(); DecrementPendingCallbacks(true); // Will dispose of GC handle. } } DisposePacketCache(); }
/// <summary> /// Dispose object /// </summary> public override void Dispose() { if (_sslOverTdsStream != null) { _sslOverTdsStream.Dispose(); _sslOverTdsStream = null; } if (_sslStream != null) { _sslStream.Dispose(); _sslStream = null; } if (_tcpStream != null) { _tcpStream.Dispose(); _tcpStream = null; } if (_sniPacket != null) { _sniPacket.Dispose(); _sniPacket = null; } //Release any references held by _stream. _stream = null; }
/// <summary> /// Process a receive error /// </summary> public void HandleReceiveError(SNIPacket packet) { Debug.Assert(Monitor.IsEntered(this), "HandleReceiveError was called without being locked."); foreach (SNIMarsHandle handle in _sessions.Values) { handle.HandleReceiveError(packet); } packet?.Dispose(); }
public void Add(SNIPacket packet) { if (!_disposed) { _packets.Push(packet); } else { // If we're disposed, then get rid of any packets added to us packet.Dispose(); } }
/// <summary> /// Generate a packet with SMUX header /// </summary> /// <param name="packet">SNI packet</param> /// <returns>Encapsulated SNI packet</returns> private SNIPacket GetSMUXEncapsulatedPacket(SNIPacket packet) { uint xSequenceNumber = _sequenceNumber; Span <byte> header = stackalloc byte[SNISMUXHeader.HEADER_LENGTH]; GetSMUXHeaderBytes(packet.Length, SNISMUXFlags.SMUX_DATA, header); SNIPacket smuxPacket = new SNIPacket(SNISMUXHeader.HEADER_LENGTH + packet.Length); smuxPacket.AppendData(header); smuxPacket.AppendPacket(packet); packet.Dispose(); return(smuxPacket); }
/// <summary> /// Send a packet /// </summary> /// <param name="handle">SNI handle</param> /// <param name="packet">SNI packet</param> /// <param name="sync">true if synchronous, false if asynchronous</param> /// <returns>SNI error status</returns> public uint WritePacket(SNIHandle handle, SNIPacket packet, bool sync) { SNIPacket clonedPacket = packet.Clone(); uint result; if (sync) { result = handle.Send(clonedPacket); clonedPacket.Dispose(); } else { result = handle.SendAsync(clonedPacket, true); } return(result); }
/// <summary> /// Process a receive completion /// </summary> /// <param name="packet">SNI packet</param> /// <param name="sniErrorCode">SNI error code</param> public void HandleReceiveComplete(SNIPacket packet, uint sniErrorCode) { SNISMUXHeader currentHeader = null; SNIPacket currentPacket = null; SNIMarsHandle currentSession = null; if (sniErrorCode != TdsEnums.SNI_SUCCESS) { lock (this) { HandleReceiveError(packet); return; } } while (true) { lock (this) { if (_currentHeaderByteCount != SNISMUXHeader.HEADER_LENGTH) { currentHeader = null; currentPacket = null; currentSession = null; while (_currentHeaderByteCount != SNISMUXHeader.HEADER_LENGTH) { int bytesTaken = packet.TakeData(_headerBytes, _currentHeaderByteCount, SNISMUXHeader.HEADER_LENGTH - _currentHeaderByteCount); _currentHeaderByteCount += bytesTaken; if (bytesTaken == 0) { packet.Dispose(); packet = null; sniErrorCode = ReceiveAsync(ref packet); if (sniErrorCode == TdsEnums.SNI_SUCCESS_IO_PENDING) { return; } HandleReceiveError(packet); return; } } _currentHeader.Read(_headerBytes); _dataBytesLeft = (int)_currentHeader.length; _currentPacket = new SNIPacket((int)_currentHeader.length); } currentHeader = _currentHeader; currentPacket = _currentPacket; if (_currentHeader.flags == (byte)SNISMUXFlags.SMUX_DATA) { if (_dataBytesLeft > 0) { int length = packet.TakeData(_currentPacket, _dataBytesLeft); _dataBytesLeft -= length; if (_dataBytesLeft > 0) { packet.Dispose(); packet = null; sniErrorCode = ReceiveAsync(ref packet); if (sniErrorCode == TdsEnums.SNI_SUCCESS_IO_PENDING) { return; } HandleReceiveError(packet); return; } } } _currentHeaderByteCount = 0; if (!_sessions.ContainsKey(_currentHeader.sessionId)) { SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.SMUX_PROV, 0, SNICommon.InvalidParameterError, string.Empty); HandleReceiveError(packet); _lowerHandle.Dispose(); _lowerHandle = null; return; } if (_currentHeader.flags == (byte)SNISMUXFlags.SMUX_FIN) { _sessions.Remove(_currentHeader.sessionId); } else { currentSession = _sessions[_currentHeader.sessionId]; } } if (currentHeader.flags == (byte)SNISMUXFlags.SMUX_DATA) { currentSession.HandleReceiveComplete(currentPacket, currentHeader); } if (_currentHeader.flags == (byte)SNISMUXFlags.SMUX_ACK) { try { currentSession.HandleAck(currentHeader.highwater); } catch (Exception e) { SNICommon.ReportSNIError(SNIProviders.SMUX_PROV, SNICommon.InternalExceptionError, e); } } lock (this) { if (packet.DataLeft == 0) { packet.Dispose(); packet = null; sniErrorCode = ReceiveAsync(ref packet); if (sniErrorCode == TdsEnums.SNI_SUCCESS_IO_PENDING) { return; } HandleReceiveError(packet); return; } } } }