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); }
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); }