Пример #1
0
        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;
                }
            }
        }
Пример #2
0
        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");
 }
Пример #4
0
        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();
     }
 }