Beispiel #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;
                }
            }
        }
        // This method should only be called by ReadSni!  If not - it may have problems with timeouts!
        private void ReadSniError(TdsParserStateObject stateObj, UInt32 error)
        {
            if (TdsEnums.SNI_WAIT_TIMEOUT == error)
            {
                Debug.Assert(_syncOverAsync, "Should never reach here with async on!");
                bool fail = false;

                if (_internalTimeout)
                { // This is now our second timeout - time to give up.
                    fail = true;
                }
                else
                {
                    stateObj._internalTimeout = true;
                    Debug.Assert(_parser.Connection != null, "SqlConnectionInternalTds handler can not be null at this point.");
                    AddError(new SqlError(TdsEnums.TIMEOUT_EXPIRED, (byte)0x00, TdsEnums.MIN_ERROR_CLASS, _parser.Server, _parser.Connection.TimeoutErrorInternal.GetErrorMessage(), "", 0, TdsEnums.SNI_WAIT_TIMEOUT));

                    if (!stateObj._attentionSent)
                    {
                        if (stateObj.Parser.State == TdsParserState.OpenLoggedIn)
                        {
                            stateObj.SendAttention(mustTakeWriteLock: true);

                            IntPtr syncReadPacket = IntPtr.Zero;

                            bool shouldDecrement = false;
                            try
                            {
                                Interlocked.Increment(ref _readingCount);
                                shouldDecrement = true;

                                SNIHandle handle = Handle;
                                if (handle == null)
                                {
                                    throw ADP.ClosedConnectionError();
                                }

                                error = SNINativeMethodWrapper.SNIReadSyncOverAsync(handle, ref syncReadPacket, stateObj.GetTimeoutRemaining());

                                Interlocked.Decrement(ref _readingCount);
                                shouldDecrement = false;

                                if (TdsEnums.SNI_SUCCESS == error)
                                {
                                    // We will end up letting the run method deal with the expected done:done_attn token stream.
                                    stateObj.ProcessSniPacket(syncReadPacket, 0);
                                    return;
                                }
                                else
                                {
                                    Debug.Assert(IntPtr.Zero == syncReadPacket, "unexpected syncReadPacket without corresponding SNIPacketRelease");
                                    fail = true; // Subsequent read failed, time to give up.
                                }
                            }
                            finally
                            {
                                if (shouldDecrement)
                                {
                                    Interlocked.Decrement(ref _readingCount);
                                }

                                if (syncReadPacket != IntPtr.Zero)
                                {
                                    // Be sure to release packet, otherwise it will be leaked by native.
                                    SNINativeMethodWrapper.SNIPacketRelease(syncReadPacket);
                                }
                            }
                        }
                        else
                        {
                            if (_parser._loginWithFailover)
                            {
                                // For DbMirroring Failover during login, never break the connection, just close the TdsParser
                                _parser.Disconnect();
                            }
                            else if ((_parser.State == TdsParserState.OpenNotLoggedIn) && (_parser.Connection.ConnectionOptions.MultiSubnetFailover))
                            {
                                // For MultiSubnet Failover during login, never break the connection, just close the TdsParser
                                _parser.Disconnect();
                            }
                            else
                                fail = true; // We aren't yet logged in - just fail.
                        }
                    }
                }

                if (fail)
                {
                    _parser.State = TdsParserState.Broken; // We failed subsequent read, we have to quit!
                    _parser.Connection.BreakConnection();
                }
            }
            else
            {
                // Caution: ProcessSNIError  always  returns a fatal error!
                AddError(_parser.ProcessSNIError(stateObj));
            }
            ThrowExceptionAndWarning();

            AssertValidState();
        }
        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 ReadSniError(TdsParserStateObject stateObj, uint error)
 {
     if (this._parser._fAwaitingPreLogin && (error != 0x102))
     {
         this._parser._fPreLoginErrorOccurred = true;
         return;
     }
     if (0x102 != error)
     {
         this._parser.Errors.Add(this._parser.ProcessSNIError(stateObj));
         goto Label_011E;
     }
     bool flag = false;
     if (this._internalTimeout)
     {
         flag = true;
     }
     else
     {
         stateObj._internalTimeout = true;
         this._parser.Errors.Add(new SqlError(-2, 0, 11, this._parser.Server, SQLMessage.Timeout(), "", 0));
         if (!stateObj._attentionSent)
         {
             if (stateObj.Parser.State == TdsParserState.OpenLoggedIn)
             {
                 stateObj.SendAttention();
                 IntPtr zero = IntPtr.Zero;
                 RuntimeHelpers.PrepareConstrainedRegions();
                 try
                 {
                     error = SNINativeMethodWrapper.SNIReadSync(stateObj.Handle, ref zero, TdsParserStaticMethods.GetTimeoutMilliseconds(stateObj.TimeoutTime));
                     if (error == 0)
                     {
                         stateObj.ProcessSniPacket(zero, 0);
                         return;
                     }
                     flag = true;
                     goto Label_00E1;
                 }
                 finally
                 {
                     if (zero != IntPtr.Zero)
                     {
                         SNINativeMethodWrapper.SNIPacketRelease(zero);
                     }
                 }
             }
             flag = true;
         }
     }
 Label_00E1:
     if (flag)
     {
         this._parser.State = TdsParserState.Broken;
         this._parser.Connection.BreakConnection();
     }
 Label_011E:
     this._parser.ThrowExceptionAndWarning();
 }
 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");
 }