Beispiel #1
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="connection">MARS connection</param>
 /// <param name="sessionId">MARS session ID</param>
 /// <param name="callbackObject">Callback object</param>
 /// <param name="async">true if connection is asynchronous</param>
 public SNIMarsHandle(SNIMarsConnection connection, ushort sessionId, TdsParserStateObject callbackObject, out SNIError sniError)
 {
     _sessionId      = sessionId;
     _connection     = connection;
     _callbackObject = callbackObject;
     sniError        = SendControlPacket(SNISMUXFlags.SMUX_SYN, true);
 }
Beispiel #2
0
        protected override void CreateSessionHandle(TdsParserStateObject physicalConnection, bool async)
        {
            Debug.Assert(physicalConnection is TdsParserStateObjectManaged, "Expected a stateObject of type " + this.GetType());
            TdsParserStateObjectManaged managedSNIObject = physicalConnection as TdsParserStateObjectManaged;

            _sessionHandle = SNIProxy.Singleton.CreateMarsHandle(this, managedSNIObject.Handle, _outBuff.Length, async);
        }
        internal void Deactivate()
        {
            IntPtr ptr;

            Bid.ScopeEnter(out ptr, "<sc.TdsParserSessionPool.Deactivate|ADV> %d# deactivating cachedCount=%d\n", this.ObjectID, this._cachedCount);
            try
            {
                lock (this._cache)
                {
                    for (int i = this._cache.Count - 1; i >= 0; i--)
                    {
                        TdsParserStateObject session = this._cache[i];
                        if ((session != null) && session.IsOrphaned)
                        {
                            if (Bid.AdvancedOn)
                            {
                                Bid.Trace("<sc.TdsParserSessionPool.Deactivate|ADV> %d# reclaiming session %d\n", this.ObjectID, session.ObjectID);
                            }
                            this.PutSession(session);
                        }
                    }
                }
            }
            finally
            {
                Bid.ScopeLeave(ref ptr);
            }
        }
        internal void PutSession(TdsParserStateObject session)
        {
            bool flag2 = session.Deactivate();

            if (!this.IsDisposed)
            {
                if (flag2 && (this._cachedCount < 10))
                {
                    if (Bid.AdvancedOn)
                    {
                        Bid.Trace("<sc.TdsParserSessionPool.PutSession|ADV> %d# keeping session %d cachedCount=%d\n", this.ObjectID, session.ObjectID, this._cachedCount);
                    }
                    this._freeStack.SynchronizedPush(session);
                }
                else
                {
                    if (Bid.AdvancedOn)
                    {
                        Bid.Trace("<sc.TdsParserSessionPool.PutSession|ADV> %d# disposing session %d cachedCount=%d\n", this.ObjectID, session.ObjectID, this._cachedCount);
                    }
                    lock (this._cache)
                    {
                        this._cache.Remove(session);
                        this._cachedCount = this._cache.Count;
                    }
                    session.Dispose();
                }
            }
        }
        internal void Deactivate()
        {
            // When being deactivated, we check all the sessions in the
            // cache to make sure they're cleaned up and then we dispose of
            // sessions that are past what we want to keep around.
            using (TryEventScope.Create("<sc.TdsParserSessionPool.Deactivate|ADV> {0} deactivating cachedCount={1}", ObjectID, _cachedCount))
            {
                lock (_cache)
                {
                    // NOTE: The PutSession call below may choose to remove the
                    //       session from the cache, which will throw off our
                    //       enumerator.  We avoid that by simply indexing backward
                    //       through the array.

                    for (int i = _cache.Count - 1; i >= 0; i--)
                    {
                        TdsParserStateObject session = _cache[i];

                        if (null != session)
                        {
                            if (session.IsOrphaned)
                            {
                                // TODO: consider adding a performance counter for the number of sessions we reclaim
                                SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.TdsParserSessionPool.Deactivate|ADV> {0} reclaiming session {1}", ObjectID, session.ObjectID);
                                PutSession(session);
                            }
                        }
                    }
                    // TODO: re-enable this assert when the connection isn't doomed.
                    //Debug.Assert (_cachedCount < MaxInactiveCount, "non-orphaned connection past initial allocation?");
                }
            }
        }
        internal SqlCachedBuffer(SqlMetaDataPriv metadata, TdsParser parser, TdsParserStateObject stateObj)
        {
            int len = 0;

            this._cachedBytes = new ArrayList();
            ulong num = parser.PlpBytesLeft(stateObj);

            do
            {
                if (num == 0L)
                {
                    return;
                }
                do
                {
                    len = (num > 0x800L) ? 0x800 : ((int)num);
                    byte[] buff = new byte[len];
                    len = stateObj.ReadPlpBytes(ref buff, 0, len);
                    if (this._cachedBytes.Count == 0)
                    {
                        this.AddByteOrderMark(buff);
                    }
                    this._cachedBytes.Add(buff);
                    num -= len;
                }while (num > 0L);
                num = parser.PlpBytesLeft(stateObj);
            }while (num > 0L);
        }
        protected override void CreateSessionHandle(TdsParserStateObject physicalConnection, bool async)
        {
            Debug.Assert(physicalConnection is TdsParserStateObjectManaged, "Expected a stateObject of type " + this.GetType());
            TdsParserStateObjectManaged managedSNIObject = physicalConnection as TdsParserStateObjectManaged;

            _sessionHandle = managedSNIObject.CreateMarsSession(this, async);
        }
Beispiel #8
0
        internal void PutSession(TdsParserStateObject session)
        {
            Debug.Assert(null != session, "null session?");

            bool okToReuse;

            _parser.Connection._parserLock.Wait(canReleaseFromAnyThread: false);
            try
            {
                okToReuse = session.Deactivate();
            }
            finally
            {
                _parser.Connection._parserLock.Release();
            }

            bool disposeSession = false;

            lock (_cache)
            {
                if (IsDisposed)
                {
                    // We're diposed - just clean out the session
                    Debug.Assert(_cache.Count == 0, "SessionPool is disposed, but there are still sessions in the cache?");
                    disposeSession = true;
                }
                else if ((okToReuse) && (_freeStateObjectCount < MaxInactiveCount))
                {
                    // Session is good to re-use and our cache has space
                    Debug.Assert(!session._pendingData, "pending data on a pooled session?");

                    _freeStateObjects[_freeStateObjectCount] = session;
                    _freeStateObjectCount++;
                }
                else
                {
                    // Either the session is bad, or we have no cache space - so dispose the session and remove it

                    bool removed = _cache.Remove(session);
                    Debug.Assert(removed, "session not in pool?");
                    disposeSession = true;
                }

                session.RemoveOwner();
            }

            if (disposeSession)
            {
                _parser.Connection._parserLock.Wait(canReleaseFromAnyThread: false);
                try
                {
                    session.Dispose();
                }
                finally
                {
                    _parser.Connection._parserLock.Release();
                }
            }
        }
Beispiel #9
0
        /// <summary>
        /// Enables MARS for a TdsParserStateObject and returns its new handle.
        /// </summary>
        public static SNIMarsHandle EnableMars(TdsParserStateObject stateObject, out SNIError sniError)
        {
            Debug.Assert(!(stateObject.Handle is SNIMarsHandle), "Cannot enable MARS on a SNIMarsHandle");
            SNIMarsConnection marsConnection = new SNIMarsConnection(stateObject.Handle);

            marsConnection.StartReceive();
            return(marsConnection.CreateSession(stateObject, out sniError));
        }
 internal TdsValueSetter(TdsParserStateObject stateObj, SmiMetaData md)
 {
     this._stateObj       = stateObj;
     this._metaData       = md;
     this._isPlp          = MetaDataUtilsSmi.IsPlpFormat(md);
     this._plpUnknownSent = false;
     this._encoder        = null;
 }
        protected override void CreateSessionHandle(TdsParserStateObject physicalConnection, bool async)
        {
            Debug.Assert(physicalConnection is TdsParserStateObjectNative, "Expected a stateObject of type " + this.GetType());
            TdsParserStateObjectNative nativeSNIObject = physicalConnection as TdsParserStateObjectNative;

            SNINativeMethodWrapper.ConsumerInfo myInfo = CreateConsumerInfo(async);
            _sessionHandle = new SNIHandle(myInfo, nativeSNIObject.Handle);
        }
 internal void SynchronizedPush(TdsParserStateObject value)
 {
     lock (this)
     {
         value.NextPooledObject = this._stack;
         this._stack            = value;
     }
 }
Beispiel #13
0
        protected override void CreateSessionHandle(TdsParserStateObject physicalConnection, bool async)
        {
            Debug.Assert(physicalConnection is TdsParserStateObjectManaged, "Expected a stateObject of type " + GetType());
            TdsParserStateObjectManaged managedSNIObject = physicalConnection as TdsParserStateObjectManaged;

            _sessionHandle = managedSNIObject.CreateMarsSession(this, async);
            SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.CreateSessionHandle | Info | State Object Id {0}, Session Id {1}", _objectID, _sessionHandle?.ConnectionId);
        }
 internal TdsRecordBufferSetter(TdsParserStateObject stateObj, SmiMetaData md)
 {
     this._fieldSetters = new TdsValueSetter[md.FieldMetaData.Count];
     for (int i = 0; i < md.FieldMetaData.Count; i++)
     {
         this._fieldSetters[i] = new TdsValueSetter(stateObj, md.FieldMetaData[i]);
     }
     this._stateObj = stateObj;
     this._metaData = md;
 }
 internal SqlCommand FindLiveCommand(TdsParserStateObject stateObj)
 {
     SqlCommand command = null;
     SqlReferenceCollection referenceCollection = (SqlReferenceCollection)ReferenceCollection;
     if (null != referenceCollection)
     {
         command = referenceCollection.FindLiveCommand(stateObj);
     }
     return command;
 }
Beispiel #16
0
 public SNIMarsHandle CreateSession(TdsParserStateObject callbackObject, out SNIError sniError)
 {
     lock (this)
     {
         ushort        sessionId = _nextSessionId++;
         SNIMarsHandle handle    = new SNIMarsHandle(this, sessionId, callbackObject, out sniError);
         _sessions.Add(sessionId, handle);
         return(handle);
     }
 }
Beispiel #17
0
        private int _currentOffset;                      // for chunking, verify that caller is using correct offsets
#endif

        #endregion

        #region Exposed Construct/factory methods

        internal TdsValueSetter(TdsParserStateObject stateObj, SmiMetaData md)
        {
            _stateObj       = stateObj;
            _metaData       = md;
            _isPlp          = MetaDataUtilsSmi.IsPlpFormat(md);
            _plpUnknownSent = false;
            _encoder        = null;
#if DEBUG
            _currentOffset = 0;
#endif
        }
 internal TdsParserStateObject CreateSessionObject(TdsParser tdsParser, TdsParserStateObject _pMarsPhysicalConObj, bool v)
 {
     if (TdsParserStateObjectFactory.UseManagedSNI)
     {
         return(new TdsParserStateObjectManaged(tdsParser, _pMarsPhysicalConObj, true));
     }
     else
     {
         return(new TdsParserStateObjectNative(tdsParser, _pMarsPhysicalConObj, true));
     }
 }
 private static void WriteDispatcher(IntPtr key, IntPtr packet, uint error)
 {
     if (IntPtr.Zero != key)
     {
         GCHandle             handle = (GCHandle)key;
         TdsParserStateObject target = (TdsParserStateObject)handle.Target;
         if (target != null)
         {
             target.WriteAsyncCallback(IntPtr.Zero, packet, error);
         }
     }
 }
Beispiel #20
0
        protected override void CreateSessionHandle(TdsParserStateObject physicalConnection, bool async)
        {
            Debug.Assert(physicalConnection is TdsParserStateObjectNative, "Expected a stateObject of type " + this.GetType());
            TdsParserStateObjectNative nativeSNIObject = physicalConnection as TdsParserStateObjectNative;

            SNINativeMethodWrapper.ConsumerInfo myInfo = CreateConsumerInfo(async);

            SQLDNSInfo cachedDNSInfo;
            bool       ret = SQLFallbackDNSCache.Instance.GetDNSInfo(_parser.FQDNforDNSCahce, out cachedDNSInfo);

            _sessionHandle = new SNIHandle(myInfo, nativeSNIObject.Handle, cachedDNSInfo);
        }
        // Reads off from the network buffer and caches bytes. Only reads one column value in the current row.
        static internal bool TryCreate(SqlMetaDataPriv metadata, TdsParser parser, TdsParserStateObject stateObj, out SqlCachedBuffer buffer)
        {
            int   cb = 0;
            ulong plplength;

            byte[] byteArr;

            List <byte[]> cachedBytes = new List <byte[]>();

            buffer = null;

            // the very first length is already read.
            if (!parser.TryPlpBytesLeft(stateObj, out plplength))
            {
                return(false);
            }
            // For now we  only handle Plp data from the parser directly.
            Debug.Assert(metadata.metaType.IsPlp, "SqlCachedBuffer call on a non-plp data");
            do
            {
                if (plplength == 0)
                {
                    break;
                }
                do
                {
                    cb      = (plplength > (ulong)_maxChunkSize) ? _maxChunkSize : (int)plplength;
                    byteArr = new byte[cb];
                    if (!stateObj.TryReadPlpBytes(ref byteArr, 0, cb, out cb))
                    {
                        return(false);
                    }
                    Debug.Assert(cb == byteArr.Length);
                    if (cachedBytes.Count == 0)
                    {
                        // Add the Byte order mark if needed if we read the first array
                        AddByteOrderMark(byteArr, cachedBytes);
                    }
                    cachedBytes.Add(byteArr);
                    plplength -= (ulong)cb;
                } while (plplength > 0);
                if (!parser.TryPlpBytesLeft(stateObj, out plplength))
                {
                    return(false);
                }
            } while (plplength > 0);
            Debug.Assert(stateObj._longlen == 0 && stateObj._longlenleft == 0);

            buffer = new SqlCachedBuffer(cachedBytes);
            return(true);
        }
        private int _currentField;                          // validate that caller sets columns in correct order.
#endif

        #endregion

        #region Exposed Construct and control methods/properties

        internal TdsRecordBufferSetter(TdsParserStateObject stateObj, SmiMetaData md)
        {
            Debug.Assert(SqlDbType.Structured == md.SqlDbType, "Unsupported SqlDbType: " + md.SqlDbType);
            _fieldSetters = new TdsValueSetter[md.FieldMetaData.Count];
            for (int i = 0; i < md.FieldMetaData.Count; i++)
            {
                _fieldSetters[i] = new TdsValueSetter(stateObj, md.FieldMetaData[i]);
            }
            _stateObj = stateObj;
            _metaData = md;
#if DEBUG
            _currentField = ReadyForToken;
#endif
        }
 // This is called from a ThreadAbort - ensure that it can be run from a CER Catch
 internal void BestEffortCleanup()
 {
     for (int i = 0; i < _cache.Count; i++)
     {
         TdsParserStateObject session = _cache[i];
         if (null != session)
         {
             var sessionHandle = session.Handle;
             if (sessionHandle != null)
             {
                 sessionHandle.Dispose();
             }
         }
     }
 }
            internal TdsParserStateObject SynchronizedPop()
            {
                TdsParserStateObject obj2;

                lock (this)
                {
                    obj2 = this._stack;
                    if (obj2 != null)
                    {
                        this._stack           = obj2.NextPooledObject;
                        obj2.NextPooledObject = null;
                    }
                }
                return(obj2);
            }
        internal TdsParserStateObject CreateSession()
        {
            TdsParserStateObject item = this._parser.CreateSession();

            lock (this._cache)
            {
                if (Bid.AdvancedOn)
                {
                    Bid.Trace("<sc.TdsParserSessionPool.CreateSession|ADV> %d# adding session %d to pool\n", this.ObjectID, item.ObjectID);
                }
                this._cache.Add(item);
                this._cachedCount = this._cache.Count;
            }
            return(item);
        }
        internal TdsParserStateObject GetSession(object owner)
        {
            TdsParserStateObject obj2 = this._freeStack.SynchronizedPop();

            if (obj2 == null)
            {
                obj2 = this.CreateSession();
            }
            obj2.Activate(owner);
            if (Bid.AdvancedOn)
            {
                Bid.Trace("<sc.TdsParserSessionPool.GetSession|ADV> %d# using session %d\n", this.ObjectID, obj2.ObjectID);
            }
            return(obj2);
        }
        internal void Deactivate()
        {
            // When being deactivated, we check all the sessions in the
            // cache to make sure they're cleaned up and then we dispose of
            // sessions that are past what we want to keep around.

            IntPtr hscp;

            Bid.ScopeEnter(out hscp, "<sc.TdsParserSessionPool.Deactivate|ADV> %d# deactivating cachedCount=%d\n", ObjectID, _cachedCount);

            try
            {
                lock (_cache)
                {
                    // NOTE: The PutSession call below may choose to remove the
                    //       session from the cache, which will throw off our
                    //       enumerator.  We avoid that by simply indexing backward
                    //       through the array.

                    for (int i = _cache.Count - 1; i >= 0; i--)
                    {
                        TdsParserStateObject session = _cache[i];

                        if (null != session)
                        {
                            if (session.IsOrphaned)
                            {
                                // TODO: consider adding a performance counter for the number of sessions we reclaim

                                if (Bid.AdvancedOn)
                                {
                                    Bid.Trace("<sc.TdsParserSessionPool.Deactivate|ADV> %d# reclaiming session %d\n", ObjectID, session.ObjectID);
                                }

                                PutSession(session);
                            }
                        }
                    }
                    // TODO: re-enable this assert when the connection isn't doomed.
                    //Debug.Assert (_cachedCount < MaxInactiveCount, "non-orphaned connection past initial allocation?");
                }
            }
            finally
            {
                Bid.ScopeLeave(ref hscp);
            }
        }
        internal void PutSession(TdsParserStateObject session)
        {
            Debug.Assert(null != session, "null session?");
            //Debug.Assert(null != session.Owner, "session without owner?");

            bool okToReuse = session.Deactivate();

            lock (_cache)
            {
                if (IsDisposed)
                {
                    // We're diposed - just clean out the session
                    Debug.Assert(_cachedCount == 0, "SessionPool is disposed, but there are still sessions in the cache?");
                    session.Dispose();
                }
                else if ((okToReuse) && (_freeStateObjectCount < MaxInactiveCount))
                {
                    // Session is good to re-use and our cache has space
                    if (Bid.AdvancedOn)
                    {
                        Bid.Trace("<sc.TdsParserSessionPool.PutSession|ADV> %d# keeping session %d cachedCount=%d\n", ObjectID, session.ObjectID, _cachedCount);
                    }
                    Debug.Assert(!session._pendingData, "pending data on a pooled session?");

                    _freeStateObjects[_freeStateObjectCount] = session;
                    _freeStateObjectCount++;
                }
                else
                {
                    // Either the session is bad, or we have no cache space - so dispose the session and remove it
                    if (Bid.AdvancedOn)
                    {
                        Bid.Trace("<sc.TdsParserSessionPool.PutSession|ADV> %d# disposing session %d cachedCount=%d\n", ObjectID, session.ObjectID, _cachedCount);
                    }

                    bool removed = _cache.Remove(session);
                    Debug.Assert(removed, "session not in pool?");
                    _cachedCount = _cache.Count;
                    session.Dispose();
                }

                session.RemoveOwner();
            }
        }
        internal void Deactivate()
        {
            // When being deactivated, we check all the sessions in the
            // cache to make sure they're cleaned up and then we dispose of
            // sessions that are past what we want to keep around.

            IntPtr hscp;

            Bid.ScopeEnter(out hscp, "<sc.TdsParserSessionPool.Deactivate|ADV> %d# deactivating cachedCount=%d\n", ObjectID, _cachedCount);

            try {
                lock (_cache) {
                    // NOTE: The PutSession call below may choose to remove the
                    //       session from the cache, which will throw off our
                    //       enumerator.  We avoid that by simply indexing backward
                    //       through the array.

                    for (int i = _cache.Count - 1; i >= 0; i--)
                    {
                        TdsParserStateObject session = _cache[i];

                        if (null != session)
                        {
                            if (session.IsOrphaned)
                            {
                                //

                                if (Bid.AdvancedOn)
                                {
                                    Bid.Trace("<sc.TdsParserSessionPool.Deactivate|ADV> %d# reclaiming session %d\n", ObjectID, session.ObjectID);
                                }

                                PutSession(session);
                            }
                        }
                    }
                    //
                }
            }
            finally {
                Bid.ScopeLeave(ref hscp);
            }
        }
        static private void ReadDispatcher(IntPtr key, IntPtr packet, UInt32 error)
        {
            // This is the app-domain dispatcher for all async read callbacks, It
            // simply gets the state object from the key that it is passed, and
            // calls the state object's read callback.
            Debug.Assert(IntPtr.Zero != key, "no key passed to read callback dispatcher?");
            if (IntPtr.Zero != key)
            {
                // NOTE: we will get a null ref here if we don't get a key that
                //       contains a GCHandle to TDSParserStateObject; that is
                //       very bad, and we want that to occur so we can catch it.
                GCHandle             gcHandle = (GCHandle)key;
                TdsParserStateObject stateObj = (TdsParserStateObject)gcHandle.Target;

                if (null != stateObj)
                {
                    stateObj.ReadAsyncCallback(IntPtr.Zero, packet, error);
                }
            }
        }