internal void FailureCleanup(TdsParserStateObject stateObj, Exception e) { int old_outputPacketNumber = stateObj._outputPacketNumber; if (stateObj.HasOpenResult) { // Need to decrement openResultCount if operation failed. stateObj.DecrementOpenResultCount(); } // be sure to wipe out our buffer if we started sending stuff stateObj.ResetBuffer(); stateObj._outputPacketNumber = 1; // end of message - reset to 1 - per ramas if (old_outputPacketNumber != 1 && _state == TdsParserState.OpenLoggedIn) { Debug.Assert(_connHandler._parserLock.ThreadMayHaveLock(), "Should not be calling into FailureCleanup without first taking the parser lock"); bool originalThreadHasParserLock = _connHandler.ThreadHasParserLockForClose; try { // Need to set this to true such that if we have an error sending\processing the attention, we won't deadlock ourselves _connHandler.ThreadHasParserLockForClose = true; // If _outputPacketNumber prior to ResetBuffer was not equal to 1, a packet was already // sent to the server and so we need to send an attention and process the attention ack. stateObj.SendAttention(); ProcessAttention(stateObj); } finally { // Reset the ThreadHasParserLock value incase our caller expects it to be set\not set _connHandler.ThreadHasParserLockForClose = originalThreadHasParserLock; } } }
internal void CheckResetConnection(TdsParserStateObject stateObj) { if (_fResetConnection && !stateObj._fResetConnectionSent) { Debug.Assert(stateObj._outputPacketNumber == 1 || stateObj._outputPacketNumber == 2, "In ResetConnection logic unexpectedly!"); try { if (_fMARS && !stateObj._fResetEventOwned) { // If using Async & MARS and we do not own ResetEvent - grab it. We need to not grab lock here // for case where multiple packets are sent to server from one execute. stateObj._fResetEventOwned = _resetConnectionEvent.WaitOne(stateObj.GetTimeoutRemaining()); if (stateObj._fResetEventOwned) { if (stateObj.TimeoutHasExpired) { // We didn't timeout on the WaitOne, but we timed out by the time we decremented stateObj._timeRemaining. stateObj._fResetEventOwned = !_resetConnectionEvent.Set(); stateObj.TimeoutTime = 0; } } if (!stateObj._fResetEventOwned) { // We timed out waiting for ResetEvent. Throw timeout exception and reset // the buffer. Nothing else to do since we did not actually send anything // to the server. stateObj.ResetBuffer(); Debug.Assert(_connHandler != null, "SqlConnectionInternalTds handler can not be null at this point."); stateObj.AddError(new SqlError(TdsEnums.TIMEOUT_EXPIRED, (byte)0x00, TdsEnums.MIN_ERROR_CLASS, _server, _connHandler.TimeoutErrorInternal.GetErrorMessage(), "", 0, TdsEnums.SNI_WAIT_TIMEOUT)); Debug.Assert(_connHandler._parserLock.ThreadMayHaveLock(), "Thread is writing without taking the connection lock"); ThrowExceptionAndWarning(stateObj, callerHasConnectionLock: true); } } if (_fResetConnection) { // Check again to see if we need to send reset. Debug.Assert(!stateObj._fResetConnectionSent, "Unexpected state for sending reset connection"); { // if we are reseting, set bit in header by or'ing with other value stateObj._outBuff[1] = (Byte)(stateObj._outBuff[1] | TdsEnums.ST_RESET_CONNECTION); } if (!_fMARS) { _fResetConnection = false; // If not MARS, can turn off flag now. } else { stateObj._fResetConnectionSent = true; // Otherwise set flag so we don't resend on multiple packet execute. } } else if (_fMARS && stateObj._fResetEventOwned) { Debug.Assert(!stateObj._fResetConnectionSent, "Unexpected state on WritePacket ResetConnection"); // Otherwise if Yukon and we grabbed the event, free it. Another execute grabbed the event and // took care of sending the reset. stateObj._fResetEventOwned = !_resetConnectionEvent.Set(); Debug.Assert(!stateObj._fResetEventOwned, "Invalid AutoResetEvent state!"); } } catch (Exception) { if (_fMARS && stateObj._fResetEventOwned) { // If exception thrown, and we are on Yukon and own the event, release it! stateObj._fResetConnectionSent = false; stateObj._fResetEventOwned = !_resetConnectionEvent.Set(); Debug.Assert(!stateObj._fResetEventOwned, "Invalid AutoResetEvent state!"); } throw; } } #if DEBUG else { Debug.Assert(!_fResetConnection || (_fResetConnection && stateObj._fResetConnectionSent && stateObj._fResetEventOwned), "Unexpected state on else ResetConnection block in WritePacket"); } #endif }
internal void FailureCleanup(TdsParserStateObject stateObj, Exception e) { int num = stateObj._outputPacketNumber; if (Bid.TraceOn) { Bid.Trace("<sc.TdsParser.FailureCleanup|ERR> Exception caught on ExecuteXXX: '%ls' \n", e.ToString()); } if (stateObj.HasOpenResult) { stateObj.DecrementOpenResultCount(); } stateObj.ResetBuffer(); stateObj._outputPacketNumber = 1; if ((num != 1) && (this._state == TdsParserState.OpenLoggedIn)) { stateObj.SendAttention(); this.ProcessAttention(stateObj); } Bid.Trace("<sc.TdsParser.FailureCleanup|ERR> Exception rethrown. \n"); }
internal void FailureCleanup(TdsParserStateObject stateObj, Exception e) { int old_outputPacketNumber = stateObj._outputPacketNumber; if (Bid.TraceOn) { Bid.Trace("<sc.TdsParser.FailureCleanup|ERR> Exception caught on ExecuteXXX: '%ls' \n", e.ToString()); } if (stateObj.HasOpenResult) { // SQL BU DT 383773 - need to decrement openResultCount if operation failed. stateObj.DecrementOpenResultCount(); } // be sure to wipe out our buffer if we started sending stuff stateObj.ResetBuffer(); stateObj._outputPacketNumber = 1; // end of message - reset to 1 - per ramas if (old_outputPacketNumber != 1 && _state == TdsParserState.OpenLoggedIn) { Debug.Assert(_connHandler._parserLock.ThreadMayHaveLock(), "Should not be calling into FailureCleanup without first taking the parser lock"); bool originalThreadHasParserLock = _connHandler.ThreadHasParserLockForClose; try { // Dev11 Bug 385286 : ExecuteNonQueryAsync hangs when trying to write a parameter which generates ArgumentException and while handling that exception the server disconnects the connection // Need to set this to true such that if we have an error sending\processing the attention, we won't deadlock ourselves _connHandler.ThreadHasParserLockForClose = true; // If _outputPacketNumber prior to ResetBuffer was not equal to 1, a packet was already // sent to the server and so we need to send an attention and process the attention ack. stateObj.SendAttention(); ProcessAttention(stateObj); } finally { // Reset the ThreadHasParserLock value incase our caller expects it to be set\not set _connHandler.ThreadHasParserLockForClose = originalThreadHasParserLock; } } Bid.Trace("<sc.TdsParser.FailureCleanup|ERR> Exception rethrown. \n"); }
internal void CheckResetConnection(TdsParserStateObject stateObj) { if (this._fResetConnection && !stateObj._fResetConnectionSent) { try { if ((this._fAsync && this._fMARS) && !stateObj._fResetEventOwned) { stateObj._fResetEventOwned = this._resetConnectionEvent.WaitOne(TdsParserStaticMethods.GetTimeoutMilliseconds(stateObj.TimeoutTime), false); if (stateObj._fResetEventOwned && stateObj.TimeoutHasExpired) { stateObj._fResetEventOwned = !this._resetConnectionEvent.Set(); stateObj.TimeoutTime = 0L; } if (!stateObj._fResetEventOwned) { stateObj.ResetBuffer(); this.Errors.Add(new SqlError(-2, 0, 11, this._server, SQLMessage.Timeout(), "", 0)); this.ThrowExceptionAndWarning(); } } if (this._fResetConnection) { if (this._fPreserveTransaction) { stateObj._outBuff[1] = (byte) (stateObj._outBuff[1] | 0x10); } else { stateObj._outBuff[1] = (byte) (stateObj._outBuff[1] | 8); } if (!this._fAsync || !this._fMARS) { this._fResetConnection = false; this._fPreserveTransaction = false; } else { stateObj._fResetConnectionSent = true; } } else if ((this._fAsync && this._fMARS) && stateObj._fResetEventOwned) { stateObj._fResetEventOwned = !this._resetConnectionEvent.Set(); } } catch (Exception) { if ((this._fAsync && this._fMARS) && stateObj._fResetEventOwned) { stateObj._fResetConnectionSent = false; stateObj._fResetEventOwned = !this._resetConnectionEvent.Set(); } throw; } } }