Пример #1
0
        private DBPooledObject GetFromPool(object owningObject)
        {
            DBPooledObject res = null;

            res = (DBPooledObject)_stackNew.Pop();
            if (res == null)
            {
                res = (DBPooledObject)_stackOld.Pop();
            }

            // Shouldn't be null, we could assert here.
            Debug.Assert(res != null, "GetFromPool called with nothing in the pool!");

            if (null != res)
            {
                res.PostPop(owningObject);
#if ALLOWTRACING
                ADP.TraceObjectPoolActivity("GetFromGeneralPool", res);
#endif //ALLOWTRACING
            }

            return(res);
        }
Пример #2
0
        public DBPooledObject GetObject(object owningObject, out bool isInTransaction)
        {
            DBPooledObject obj = null;

            isInTransaction = false;

            if (_state != State.Running)
            {
                return(null);
            }

            // Try to get from the context if we're context specific:
            obj = TryGetResourceFromContext(out isInTransaction);

            if (null != obj)
            {
                obj.PostPop(owningObject);
            }
            else
            {
#if USECOUNTEROBJECT
                _poolCounter.Modify(cAddWait);
#else //!USECOUNTEROBJECT
                Interlocked.Increment(ref _waitCount);
#endif //!USECOUNTEROBJECT

                ObjectPoolWaitHandle[] localWaitHandles = _waitHandles;

                while (obj == null)
                {
                    int r = WaitHandle.WaitAny(localWaitHandles, PoolControl.CreationTimeout, false);

                    // From the WaitAny docs: "If more than one object became signaled during
                    // the call, this is the array index of the signaled object with the
                    // smallest index value of all the signaled objects."  This is important
                    // so that the free object signal will be returned before a creation
                    // signal.

                    switch (r)
                    {
                    case WAIT_TIMEOUT:
#if USECOUNTEROBJECT
                        _poolCounter.Modify(-cAddWait);
#else //!USECOUNTEROBJECT
                        Interlocked.Decrement(ref _waitCount);
#endif //!USECOUNTEROBJECT
                        return(null);

                    case ERROR_HANDLE:
                        // Throw the error that PoolCreateRequest stashed.
#if USECOUNTEROBJECT
                        _poolCounter.Modify(-cAddWait);
#else //!USECOUNTEROBJECT
                        Interlocked.Decrement(ref _waitCount);
#endif //!USECOUNTEROBJECT
                        throw _resError;

                    case CREATION_HANDLE:
                        try {
                            obj = UserCreateRequest();

                            if (null != obj)
                            {
                                obj.PostPop(owningObject);
#if USECOUNTEROBJECT
                                _poolCounter.Modify(-cAddWait);
#else //!USECOUNTEROBJECT
                                Interlocked.Decrement(ref _waitCount);
#endif //!USECOUNTEROBJECT
                            }
                            else
                            {
                                // If we were not able to create an object, check to see if
                                // we reached MaxPool.  If so, we will no longer wait on the
                                // CreationHandle, but instead wait for a free object or
                                // the timeout.

                                // BUG - if we receive the CreationHandle midway into the wait
                                // period and re-wait, we will be waiting on the full period
#if USECOUNTEROBJECT
                                if (_poolCounter.TotalCount == PoolControl.MaxPool)
                                {
#else //!USECOUNTEROBJECT
                                if (Count >= PoolControl.MaxPool)
                                {
#endif //!USECOUNTEROBJECT
                                    if (!ReclaimEmancipatedObjects())
                                    {
                                        // modify handle array not to wait on creation mutex anymore
                                        localWaitHandles    = new ObjectPoolWaitHandle[2];
                                        localWaitHandles[0] = _waitHandles[0];
                                        localWaitHandles[1] = _waitHandles[1];
                                    }
                                }
                            }
                        }
                        finally {
                            _creationMutex.ReleaseMutex();
                        }
                        break;

                    default:
                        //
                        //  guaranteed available inventory
                        //
#if USECOUNTEROBJECT
                        _poolCounter.Modify(-cAddWait - cAddFree);
#else //!USECOUNTEROBJECT
                        Interlocked.Decrement(ref _waitCount);
#endif //!USECOUNTEROBJECT
                        obj = GetFromPool(owningObject);
                        break;
                    }
                }
            }
            Debug.Assert(obj != null, "Failed to create pooled object, resulted in null instance.");

            if (null != obj)
            {
                obj.Activate();
            }

            return(obj);
        }