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; } } }
private bool TryProcessDone(SqlCommand cmd, SqlDataReader reader, ref RunBehavior run, TdsParserStateObject stateObj) { ushort curCmd; ushort status; int count; // Can't retry TryProcessDone stateObj._syncOverAsync = true; // status // command // rowcount (valid only if DONE_COUNT bit is set) if (!stateObj.TryReadUInt16(out status)) { return false; } if (!stateObj.TryReadUInt16(out curCmd)) { return false; } long longCount; if (!stateObj.TryReadInt64(out longCount)) { return false; } count = (int)longCount; // We get a done token with the attention bit set if (TdsEnums.DONE_ATTN == (status & TdsEnums.DONE_ATTN)) { Debug.Assert(TdsEnums.DONE_MORE != (status & TdsEnums.DONE_MORE), "Not expecting DONE_MORE when receiving DONE_ATTN"); Debug.Assert(stateObj._attentionSent, "Received attention done without sending one!"); stateObj._attentionReceived = true; Debug.Assert(stateObj._inBytesUsed == stateObj._inBytesRead && stateObj._inBytesPacket == 0, "DONE_ATTN received with more data left on wire"); } if ((null != cmd) && (TdsEnums.DONE_COUNT == (status & TdsEnums.DONE_COUNT))) { if (curCmd != TdsEnums.SELECT) { cmd.InternalRecordsAffected = count; } // Skip the bogus DONE counts sent by the server if (stateObj._receivedColMetaData || (curCmd != TdsEnums.SELECT)) { cmd.OnStatementCompleted(count); } } stateObj._receivedColMetaData = false; // Surface exception for DONE_ERROR in the case we did not receive an error token // in the stream, but an error occurred. In these cases, we throw a general server error. The // situations where this can occur are: an invalid buffer received from client, login error // and the server refused our connection, and the case where we are trying to log in but // the server has reached its max connection limit. Bottom line, we need to throw general // error in the cases where we did not receive a error token along with the DONE_ERROR. if ((TdsEnums.DONE_ERROR == (TdsEnums.DONE_ERROR & status)) && stateObj.ErrorCount == 0 && stateObj._errorTokenReceived == false && (RunBehavior.Clean != (RunBehavior.Clean & run))) { stateObj.AddError(new SqlError(0, 0, TdsEnums.MIN_ERROR_CLASS, _server, SQLMessage.SevereError(), "", 0)); if (null != reader) { if (!reader.IsInitialized) { run = RunBehavior.UntilDone; } } } // Similar to above, only with a more severe error. In this case, if we received // the done_srverror, this exception will be added to the collection regardless. // The server will always break the connection in this case. if ((TdsEnums.DONE_SRVERROR == (TdsEnums.DONE_SRVERROR & status)) && (RunBehavior.Clean != (RunBehavior.Clean & run))) { stateObj.AddError(new SqlError(0, 0, TdsEnums.FATAL_ERROR_CLASS, _server, SQLMessage.SevereError(), "", 0)); if (null != reader) { if (!reader.IsInitialized) { run = RunBehavior.UntilDone; } } } ProcessSqlStatistics(curCmd, status, count); // stop if the DONE_MORE bit isn't set (see above for attention handling) if (TdsEnums.DONE_MORE != (status & TdsEnums.DONE_MORE)) { stateObj._errorTokenReceived = false; if (stateObj._inBytesUsed >= stateObj._inBytesRead) { stateObj._pendingData = false; } } // _pendingData set by e.g. 'TdsExecuteSQLBatch' // _hasOpenResult always set to true by 'WriteMarsHeader' // if (!stateObj._pendingData && stateObj._hasOpenResult) { /* Debug.Assert(!((sqlTransaction != null && _distributedTransaction != null) || (_userStartedLocalTransaction != null && _distributedTransaction != null)) , "ProcessDone - have both distributed and local transactions not null!"); */ // WebData 112722 stateObj.DecrementOpenResultCount(); } return true; }
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"); }
private void ProcessDone(SqlCommand cmd, SqlDataReader reader, ref RunBehavior run, TdsParserStateObject stateObj) { int num2; ushort status = stateObj.ReadUInt16(); ushort curCmd = stateObj.ReadUInt16(); if (this._isYukon) { num2 = (int) stateObj.ReadInt64(); } else { num2 = stateObj.ReadInt32(); if (((this._state == TdsParserState.OpenNotLoggedIn) && (stateObj._inBytesRead > stateObj._inBytesUsed)) && (stateObj.PeekByte() == 0)) { num2 = stateObj.ReadInt32(); } } if (0x20 == (status & 0x20)) { stateObj._attentionReceived = true; } if ((cmd != null) && (0x10 == (status & 0x10))) { if (curCmd != 0xc1) { cmd.InternalRecordsAffected = num2; } if (stateObj._receivedColMetaData || (curCmd != 0xc1)) { cmd.OnStatementCompleted(num2); } } stateObj._receivedColMetaData = false; if (((2 == (2 & status)) && (this._errors == null)) && (!stateObj._errorTokenReceived && (RunBehavior.Clean != (RunBehavior.Clean & run)))) { this.Errors.Add(new SqlError(0, 0, 11, this._server, SQLMessage.SevereError(), "", 0)); if ((reader != null) && !reader.IsInitialized) { run = RunBehavior.UntilDone; } } if ((0x100 == (0x100 & status)) && (RunBehavior.Clean != (RunBehavior.Clean & run))) { this.Errors.Add(new SqlError(0, 0, 20, this._server, SQLMessage.SevereError(), "", 0)); if ((reader != null) && !reader.IsInitialized) { run = RunBehavior.UntilDone; } } this.ProcessSqlStatistics(curCmd, status, num2); if (1 != (status & 1)) { stateObj._errorTokenReceived = false; if (stateObj._inBytesUsed >= stateObj._inBytesRead) { stateObj._pendingData = false; } } if (!stateObj._pendingData && stateObj._hasOpenResult) { stateObj.DecrementOpenResultCount(); } }