Пример #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
        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");
 }
Пример #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");
        }
 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;
         }
     }
 }