public void Add(SNIPacket packet) {
     if (!_disposed) {
         _packets.Push(packet);
     }
     else {
         // If we're disposed, then get rid of any packets added to us
         packet.Dispose();
     }
 }
 internal void Dispose()
 {
     SafeHandle handle2 = this._sniPacket;
     SafeHandle handle = this._sessionHandle;
     SafeHandle handle3 = this._sniAsyncAttnPacket;
     this._sniPacket = null;
     this._sessionHandle = null;
     this._sniAsyncAttnPacket = null;
     if ((handle != null) || (handle2 != null))
     {
         RuntimeHelpers.PrepareConstrainedRegions();
         try
         {
         }
         finally
         {
             if (handle2 != null)
             {
                 handle2.Dispose();
             }
             if (handle3 != null)
             {
                 handle3.Dispose();
             }
             if (handle != null)
             {
                 handle.Dispose();
                 this.DecrementPendingCallbacks(true);
             }
         }
     }
 }
 public SNIPacket Take(SNIHandle sniHandle) {
     SNIPacket packet;
     if (_packets.Count > 0) {
         // Success - reset the packet
         packet = _packets.Pop();
         SNINativeMethodWrapper.SNIPacketReset(sniHandle, SNINativeMethodWrapper.IOType.WRITE, packet, SNINativeMethodWrapper.ConsumerNumber.SNI_Consumer_SNI);
     }
     else {
         // Failed to take a packet - create a new one
         packet = new SNIPacket(sniHandle);
     }
     return packet;
 }
Example #4
0
 public static uint SNIWritePacket(SafeHandle handle, SNIPacket packet, bool sync)
 {
     throw new NotSupportedException(msg);
 }
 private void WriteSni()
 {
     uint num;
     if (this._sniPacket == null)
     {
         this._sniPacket = new SNIPacket(this.Handle);
     }
     else
     {
         SNINativeMethodWrapper.SNIPacketReset(this.Handle, SNINativeMethodWrapper.IOType.WRITE, this._sniPacket, SNINativeMethodWrapper.ConsumerNumber.SNI_Consumer_SNI);
     }
     SNINativeMethodWrapper.SNIPacketSetData(this._sniPacket, this._outBuff, this._outBytesUsed);
     if (this._parser.AsyncOn)
     {
         if (this._cachedAsyncResult == null)
         {
             this._cachedAsyncResult = new DbAsyncResult(this._parser, string.Empty, null, null, null);
         }
         this._asyncResult = this._cachedAsyncResult;
         num = this.SNIWriteAsync(this.Handle, this._sniPacket, this._cachedAsyncResult);
     }
     else
     {
         num = SNINativeMethodWrapper.SNIWriteSync(this.Handle, this._sniPacket);
         if (num != 0)
         {
             Bid.Trace("<sc.TdsParser.WritePacket|Info> write sync returned error code %d\n", (int) num);
             this._parser.Errors.Add(this._parser.ProcessSNIError(this));
             this.ThrowExceptionAndWarning();
         }
         if (this._bulkCopyOpperationInProgress && (TdsParserStaticMethods.GetTimeoutMilliseconds(this.TimeoutTime) == 0))
         {
             this._parser.Errors.Add(new SqlError(-2, 0, 11, this._parser.Server, SQLMessage.Timeout(), "", 0));
             this.SendAttention();
             this._parser.ProcessPendingAck(this);
             this._parser.ThrowExceptionAndWarning();
         }
     }
     if ((this._parser.State == TdsParserState.OpenNotLoggedIn) && (this._parser.EncryptionOptions == EncryptionOptions.LOGIN))
     {
         this._parser.RemoveEncryption();
         this._parser.EncryptionOptions = EncryptionOptions.OFF;
         this._sniPacket.Dispose();
         this._sniPacket = new SNIPacket(this.Handle);
     }
     this.SniWriteStatisticsAndTracing();
     this.ResetBuffer();
 }
Example #6
0
 internal SNIPacket GetResetWritePacket()
 {
     if (_sniPacket != null)
     {
         SNINativeMethodWrapper.SNIPacketReset(Handle, SNINativeMethodWrapper.IOType.WRITE, _sniPacket, SNINativeMethodWrapper.ConsumerNumber.SNI_Consumer_SNI);
     }
     else
     {
         lock (_writePacketLockObject)
         {
             _sniPacket = _writePacketCache.Take(Handle);
         }
     }
     return _sniPacket;
 }
Example #7
0
        private IntPtr AddPacketToPendingList(SNIPacket packet)
        {
            Debug.Assert(packet == _sniPacket, "Adding a packet other than the current packet to the pending list");
            _sniPacket = null;
            IntPtr pointer = packet.DangerousGetHandle();

            lock (_writePacketLockObject)
            {
                _pendingWritePackets.Add(pointer, packet);
            }

            return pointer;
        }
 private static unsafe extern void SNIPacketSetData(SNIPacket pPacket, [In] byte* pbBuf, uint cbBuf);
 internal static unsafe void SNIPacketSetData(SNIPacket packet, byte[] data, int length)
 {
     fixed (byte* pin_data = &data[0])
     {
         SNIPacketSetData(packet, pin_data, (uint)length);
     }
 }
Example #10
0
 private static extern uint SNIWriteSyncOverAsync(SNIHandle pConn, [In] SNIPacket pPacket);
 internal static extern void SNIPacketReset([In] SNIHandle pConn, IOType IOType, SNIPacket pPacket, ConsumerNumber ConsNum);
Example #12
0
 private static extern uint SNIWriteAsyncWrapper(SNIHandle pConn, [In] SNIPacket pPacket);
Example #13
0
 private static extern unsafe void SNIPacketSetData(SNIPacket pPacket, [In] byte *pbBuf, uint cbBuf);
Example #14
0
 internal static extern void SNIPacketReset([In] SNIHandle pConn, IOType IOType, SNIPacket pPacket, ConsumerNumber ConsNum);
Example #15
0
#pragma warning disable 0420 // a reference to a volatile field will not be treated as volatile

        private Task SNIWritePacket(SNIHandle handle, SNIPacket packet, out UInt32 sniError, bool canAccumulate, bool callerHasConnectionLock)
        {
            // Check for a stored exception
            var delayedException = Interlocked.Exchange(ref _delayedWriteAsyncCallbackException, null);
            if (delayedException != null)
            {
                throw delayedException;
            }

            Task task = null;
            _writeCompletionSource = null;
            IntPtr packetPointer = IntPtr.Zero;
            bool sync = !_parser._asyncWrite;
            if (sync && _asyncWriteCount > 0)
            { // for example, SendAttention while there are writes pending
                Task waitForWrites = WaitForAccumulatedWrites();
                if (waitForWrites != null)
                {
                    try
                    {
                        waitForWrites.Wait();
                    }
                    catch (AggregateException ae)
                    {
                        throw ae.InnerException;
                    }
                }
                Debug.Assert(_asyncWriteCount == 0, "All async write should be finished");
            }
            if (!sync)
            {
                // Add packet to the pending list (since the callback can happen any time after we call SNIWritePacket)
                packetPointer = AddPacketToPendingList(packet);
            }
            // Async operation completion may be delayed (success pending).
            try
            {
            }
            finally
            {
                sniError = SNINativeMethodWrapper.SNIWritePacket(handle, packet, sync);
            }
            if (sniError == TdsEnums.SNI_SUCCESS_IO_PENDING)
            {
                Debug.Assert(!sync, "Completion should be handled in SniManagedWwrapper");
                Interlocked.Increment(ref _asyncWriteCount);
                Debug.Assert(_asyncWriteCount >= 0);
                if (!canAccumulate)
                {
                    // Create completion source (for callback to complete)
                    _writeCompletionSource = new TaskCompletionSource<object>();
                    task = _writeCompletionSource.Task;

                    // Ensure that setting _writeCompletionSource completes before checking _delayedWriteAsyncCallbackException
                    Interlocked.MemoryBarrier();

                    // Check for a stored exception
                    delayedException = Interlocked.Exchange(ref _delayedWriteAsyncCallbackException, null);
                    if (delayedException != null)
                    {
                        throw delayedException;
                    }

                    // If there are no outstanding writes, see if we can shortcut and return null
                    if ((_asyncWriteCount == 0) && ((!task.IsCompleted) || (task.Exception == null)))
                    {
                        task = null;
                    }
                }
            }
#if DEBUG
            else if (!sync && !canAccumulate && SqlCommand.DebugForceAsyncWriteDelay > 0)
            {
                // Executed synchronously - callback will not be called 
                TaskCompletionSource<object> completion = new TaskCompletionSource<object>();
                uint error = sniError;
                new Timer(obj =>
                {
                    try
                    {
                        if (_parser.MARSOn)
                        { // Only take reset lock on MARS.
                            CheckSetResetConnectionState(error, CallbackType.Write);
                        }

                        if (error != TdsEnums.SNI_SUCCESS)
                        {
                            AddError(_parser.ProcessSNIError(this));
                            ThrowExceptionAndWarning();
                        }
                        AssertValidState();
                        completion.SetResult(null);
                    }
                    catch (Exception e)
                    {
                        completion.SetException(e);
                    }
                }, null, SqlCommand.DebugForceAsyncWriteDelay, Timeout.Infinite);
                task = completion.Task;
            }
#endif
            else
            {
                if (_parser.MARSOn)
                { // Only take reset lock on MARS.
                    CheckSetResetConnectionState(sniError, CallbackType.Write);
                }

                if (sniError == TdsEnums.SNI_SUCCESS)
                {
                    _lastSuccessfulIOTimer._value = DateTime.UtcNow.Ticks;

                    if (!sync)
                    {
                        // Since there will be no callback, remove the packet from the pending list
                        Debug.Assert(packetPointer != IntPtr.Zero, "Packet added to list has an invalid pointer, can not remove from pending list");
                        RemovePacketFromPendingList(packetPointer);
                    }
                }
                else
                {
                    AddError(_parser.ProcessSNIError(this));
                    ThrowExceptionAndWarning(callerHasConnectionLock);
                }
                AssertValidState();
            }
            return task;
        }
 internal static uint SNIWritePacket(SNIHandle pConn, SNIPacket packet, bool sync)
 {
     if (sync)
     {
         return SNIWriteSyncOverAsync(pConn, packet);
     }
     else
     {
         return SNIWriteAsyncWrapper(pConn, packet);
     }
 }
Example #17
0
#pragma warning restore 0420

        // Sends an attention signal - executing thread will consume attn.
        internal void SendAttention(bool mustTakeWriteLock = false)
        {
            if (!_attentionSent)
            {
                // Dumps contents of buffer to OOB write (currently only used for
                // attentions.  There is no body for this message
                // Doesn't touch this._outBytesUsed
                if (_parser.State == TdsParserState.Closed || _parser.State == TdsParserState.Broken)
                {
                    return;
                }

                SNIPacket attnPacket = new SNIPacket(Handle);
                _sniAsyncAttnPacket = attnPacket;

                SNINativeMethodWrapper.SNIPacketSetData(attnPacket, SQL.AttentionHeader, TdsEnums.HEADER_LEN);
                try
                {
                    // Dev11 #344723: SqlClient stress hang System_Data!Tcp::ReadSync via a call to SqlDataReader::Close
                    // Set _attentionSending to true before sending attention and reset after setting _attentionSent
                    // This prevents a race condition between receiving the attention ACK and setting _attentionSent
                    _attentionSending = true;

#if DEBUG
                    if (!_skipSendAttention)
                    {
#endif
                        // Take lock and send attention
                        bool releaseLock = false;
                        if ((mustTakeWriteLock) && (!_parser.Connection.ThreadHasParserLockForClose))
                        {
                            releaseLock = true;
                            _parser.Connection._parserLock.Wait(canReleaseFromAnyThread: false);
                            _parser.Connection.ThreadHasParserLockForClose = true;
                        }
                        try
                        {
                            // Check again (just in case the connection was closed while we were waiting)
                            if (_parser.State == TdsParserState.Closed || _parser.State == TdsParserState.Broken)
                            {
                                return;
                            }

                            UInt32 sniError;
                            _parser._asyncWrite = false; // stop async write 
                            SNIWritePacket(Handle, attnPacket, out sniError, canAccumulate: false, callerHasConnectionLock: false);
                        }
                        finally
                        {
                            if (releaseLock)
                            {
                                _parser.Connection.ThreadHasParserLockForClose = false;
                                _parser.Connection._parserLock.Release();
                            }
                        }
#if DEBUG
                    }
#endif

                    SetTimeoutSeconds(AttentionTimeoutSeconds); // Initialize new attention timeout of 5 seconds.
                    _attentionSent = true;
                }
                finally
                {
                    _attentionSending = false;
                }


                AssertValidState();
            }
        }
 internal void SendAttention()
 {
     if (!this._attentionSent && ((this._parser.State != TdsParserState.Closed) && (this._parser.State != TdsParserState.Broken)))
     {
         uint num;
         SNIPacket packet = new SNIPacket(this.Handle);
         if (this._parser.AsyncOn)
         {
             this._sniAsyncAttnPacket = packet;
             if (this._asyncAttentionResult == null)
             {
                 this._asyncAttentionResult = new DbAsyncResult(this._parser, string.Empty, null, null, null);
             }
         }
         else
         {
             this._sniAsyncAttnPacket = null;
         }
         SNINativeMethodWrapper.SNIPacketSetData(packet, SQL.AttentionHeader, 8);
         if (this._parser.AsyncOn)
         {
             num = this.SNIWriteAsync(this.Handle, packet, this._asyncAttentionResult);
             Bid.Trace("<sc.TdsParser.SendAttention|Info> Send Attention ASync .\n");
         }
         else
         {
             num = SNINativeMethodWrapper.SNIWriteSync(this.Handle, packet);
             Bid.Trace("<sc.TdsParser.SendAttention|Info> Send Attention Sync.\n");
             if (num != 0)
             {
                 Bid.Trace("<sc.TdsParser.SendAttention|Info> SNIWriteSync returned error code %d\n", (int) num);
                 this._parser.Errors.Add(this._parser.ProcessSNIError(this));
                 this._parser.ThrowExceptionAndWarning();
             }
         }
         this.SetTimeoutSeconds(5);
         this._attentionSent = true;
         if (Bid.AdvancedOn)
         {
             Bid.TraceBin("<sc.TdsParser.WritePacket|INFO|ADV>  Packet sent", this._outBuff, (ushort) this._outBytesUsed);
         }
         Bid.Trace("<sc.TdsParser.SendAttention|Info> Attention sent to the server.\n");
     }
 }
Example #19
0
 internal void ClearAllWritePackets()
 {
     if (_sniPacket != null)
     {
         _sniPacket.Dispose();
         _sniPacket = null;
     }
     lock (_writePacketLockObject)
     {
         Debug.Assert(_pendingWritePackets.Count == 0 && _asyncWriteCount == 0, "Should not clear all write packets if there are packets pending");
         _writePacketCache.Clear();
     }
 }
 private uint SNIWriteAsync(SNIHandle handle, SNIPacket packet, DbAsyncResult asyncResult)
 {
     uint num;
     RuntimeHelpers.PrepareConstrainedRegions();
     try
     {
     }
     finally
     {
         this.IncrementPendingCallbacks();
         num = SNINativeMethodWrapper.SNIWriteAsync(handle, packet);
         if ((num == 0) || (num != 0x3e5))
         {
             this.DecrementPendingCallbacks(false);
         }
     }
     if (num != 0)
     {
         if (num != 0x3e5)
         {
             Bid.Trace("<sc.TdsParser.WritePacket|Info> write async returned error code %d\n", (int) num);
             this._parser.Errors.Add(this._parser.ProcessSNIError(this));
             this.ThrowExceptionAndWarning();
             return num;
         }
         if (num != 0x3e5)
         {
             return num;
         }
         try
         {
             ((IAsyncResult) asyncResult).AsyncWaitHandle.WaitOne();
             if (this._error != null)
             {
                 this._parser.Errors.Add(this._error);
                 this._error = null;
                 Bid.Trace("<sc.TdsParser.WritePacket|Info> write async returned error code %d\n", (int) num);
                 this.ThrowExceptionAndWarning();
             }
         }
         finally
         {
             asyncResult.Reset();
         }
     }
     return num;
 }
Example #21
0
        internal void Dispose()
        {
            SafeHandle packetHandle = _sniPacket;
            SafeHandle sessionHandle = _sessionHandle;
            SafeHandle asyncAttnPacket = _sniAsyncAttnPacket;

            _sniPacket = null;
            _sessionHandle = null;
            _sniAsyncAttnPacket = null;

            Timer networkPacketTimeout = _networkPacketTimeout;
            if (networkPacketTimeout != null)
            {
                _networkPacketTimeout = null;
                networkPacketTimeout.Dispose();
            }

            Debug.Assert(Volatile.Read(ref _readingCount) >= 0, "_readingCount is negative");
            if (Volatile.Read(ref _readingCount) > 0)
            {
                // if _reading is true, we need to wait for it to complete
                // if _reading is false, then future read attempts will
                // already see the null _sessionHandle and abort.

                // We block after nulling _sessionHandle but before disposing it
                // to give a chance for a read that has already grabbed the
                // handle to complete.
                SpinWait.SpinUntil(() => Volatile.Read(ref _readingCount) == 0);
            }

            if (null != sessionHandle || null != packetHandle)
            {
                try { }
                finally
                {
                    if (packetHandle != null)
                    {
                        packetHandle.Dispose();
                    }
                    if (asyncAttnPacket != null)
                    {
                        asyncAttnPacket.Dispose();
                    }
                    if (sessionHandle != null)
                    {
                        sessionHandle.Dispose();
                        DecrementPendingCallbacks(true); // Will dispose of GC handle.
                    }
                }
            }

            if (_writePacketCache != null)
            {
                lock (_writePacketLockObject)
                {
                    try { }
                    finally
                    {
                        _writePacketCache.Dispose();
                        // Do not set _writePacketCache to null, just in case a WriteAsyncCallback completes after this point
                    }
                }
            }
        }
Example #22
0
		public static uint SNIWritePacket (SafeHandle handle, SNIPacket packet, bool sync)
		{
			throw new NotSupportedException (msg);
		}