Exemplo n.º 1
0
        private bool TryGetConnection(DbConnection owningObject, uint waitForMultipleObjectsTimeout, bool allowCreate, bool onlyOneCheckConnection, DbConnectionOptions userOptions, out DbConnectionInternal connection)
        {
            DbConnectionInternal obj = null;

            if (null == obj)
            {
                Interlocked.Increment(ref _waitCount);

                do
                {
                    int waitResult = BOGUS_HANDLE;
                    try
                    {
                        try
                        {
                        }
                        finally
                        {
                            waitResult = WaitHandle.WaitAny(_waitHandles.GetHandles(allowCreate), unchecked ((int)waitForMultipleObjectsTimeout));
                        }

                        // 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 (waitResult)
                        {
                        case WaitHandle.WaitTimeout:
                            Interlocked.Decrement(ref _waitCount);
                            connection = null;
                            return(false);

                        case ERROR_HANDLE:
                            // Throw the error that PoolCreateRequest stashed.
                            Interlocked.Decrement(ref _waitCount);
                            throw TryCloneCachedException();

                        case CREATION_HANDLE:

                            try
                            {
                                obj = UserCreateRequest(owningObject, userOptions);
                            }
                            catch
                            {
                                if (null == obj)
                                {
                                    Interlocked.Decrement(ref _waitCount);
                                }
                                throw;
                            }
                            finally
                            {
                                // Ensure that we release this waiter, regardless
                                // of any exceptions that may be thrown.
                                if (null != obj)
                                {
                                    Interlocked.Decrement(ref _waitCount);
                                }
                            }

                            if (null == obj)
                            {
                                // If we were not able to create an object, check to see if
                                // we reached MaxPoolSize.  If so, we will no longer wait on
                                // the CreationHandle, but instead wait for a free object or
                                // the timeout.
                                if (Count >= MaxPoolSize && 0 != MaxPoolSize)
                                {
                                    if (!ReclaimEmancipatedObjects())
                                    {
                                        // modify handle array not to wait on creation mutex anymore
                                        Debug.Assert(2 == CREATION_HANDLE, "creation handle changed value");
                                        allowCreate = false;
                                    }
                                }
                            }
                            break;

                        case SEMAPHORE_HANDLE:
                            //
                            //    guaranteed available inventory
                            //
                            Interlocked.Decrement(ref _waitCount);
                            obj = GetFromGeneralPool();

                            if ((obj != null) && (!obj.IsConnectionAlive()))
                            {
                                DestroyObject(obj);
                                obj = null;         // Setting to null in case creating a new object fails

                                if (onlyOneCheckConnection)
                                {
                                    if (_waitHandles.CreationSemaphore.WaitOne(unchecked ((int)waitForMultipleObjectsTimeout)))
                                    {
                                        try
                                        {
                                            obj = UserCreateRequest(owningObject, userOptions);
                                        }
                                        finally
                                        {
                                            _waitHandles.CreationSemaphore.Release(1);
                                        }
                                    }
                                    else
                                    {
                                        // Timeout waiting for creation semaphore - return null
                                        connection = null;
                                        return(false);
                                    }
                                }
                            }
                            break;

                        default:
                            Interlocked.Decrement(ref _waitCount);
                            throw ADP.InternalError(ADP.InternalErrorCode.UnexpectedWaitAnyResult);
                        }
                    }
                    finally
                    {
                        if (CREATION_HANDLE == waitResult)
                        {
                            _waitHandles.CreationSemaphore.Release(1);
                        }
                    }
                } while (null == obj);
            }

            if (null != obj)
            {
                PrepareConnection(owningObject, obj);
            }

            connection = obj;
            return(true);
        }
Exemplo n.º 2
0
        private bool TryGetConnection(DbConnection owningObject, int waitForMultipleObjectsTimeout, bool allowCreate, bool onlyOneCheckConnection, DbConnectionOptions userOptions, out DbConnectionInternal connection)
        {
            DbConnectionInternal obj = null;

            if (null == obj)
            {
                Interlocked.Increment(ref _waitCount);

                do
                {
                    int waitResult = WaitHandle.WaitTimeout;
                    try
                    {
                        if (!allowCreate)
                        {
                            if (_waitHandles.PoolSemaphore.Wait(waitForMultipleObjectsTimeout))
                            {
                                waitResult = SEMAPHORE_HANDLE;
                            }
                            else
                            {
                                waitResult = WaitHandle.WaitTimeout;
                            }
                        }
                        else
                        {
                            bool     obtainedPoolSemaphore = false;
                            DateTime start = DateTime.UtcNow;
                            do
                            {
                                waitResult = WaitHandle.WaitAny(_waitHandles.Handles, waitForMultipleObjectsTimeout);

                                // Obtaining the WaitHandle for a SemaphoreSlim doesn't actually take one from the count
                                // So we need to wait on the SemaphoreSlim seperately
                                if (waitResult == SEMAPHORE_HANDLE)
                                {
                                    if (_waitHandles.PoolSemaphore.Wait(TimeSpan.Zero))
                                    {
                                        obtainedPoolSemaphore = true;
                                    }
                                    else
                                    {
                                        DateTime currentTime = DateTime.UtcNow;
                                        waitForMultipleObjectsTimeout -= (currentTime - start).Milliseconds;
                                    }
                                }
                            } while ((waitResult == SEMAPHORE_HANDLE) && !obtainedPoolSemaphore);
                        }

                        // 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 (waitResult)
                        {
                        case WaitHandle.WaitTimeout:
                            Interlocked.Decrement(ref _waitCount);
                            connection = null;
                            return(false);

                        case CREATION_HANDLE:
                            try
                            {
                                obj = UserCreateRequest(owningObject, userOptions);
                            }
                            catch
                            {
                                if (null == obj)
                                {
                                    Interlocked.Decrement(ref _waitCount);
                                }
                                throw;
                            }
                            finally
                            {
                                // Ensure that we release this waiter, regardless
                                // of any exceptions that may be thrown.
                                if (null != obj)
                                {
                                    Interlocked.Decrement(ref _waitCount);
                                }
                            }

                            if (null == obj)
                            {
                                // If we were not able to create an object, check to see if
                                // we reached MaxPoolSize.  If so, we will no longer wait on
                                // the CreationHandle, but instead wait for a free object or
                                // the timeout.
                                if (Count >= MaxPoolSize && 0 != MaxPoolSize)
                                {
                                    if (!ReclaimEmancipatedObjects())
                                    {
                                        // modify handle array not to wait on creation mutex anymore
                                        allowCreate = false;
                                    }
                                }
                            }
                            break;

                        case SEMAPHORE_HANDLE:
                            //
                            //    guaranteed available inventory
                            //
                            Interlocked.Decrement(ref _waitCount);
                            obj = GetFromGeneralPool();

                            if ((obj != null) && (!obj.IsConnectionAlive()))
                            {
                                DestroyObject(obj);
                                obj = null;         // Setting to null in case creating a new object fails

                                if (onlyOneCheckConnection)
                                {
                                    if (_waitHandles.CreationSemaphore.WaitOne(unchecked ((int)waitForMultipleObjectsTimeout)))
                                    {
                                        try
                                        {
                                            obj = UserCreateRequest(owningObject, userOptions);
                                        }
                                        finally
                                        {
                                            _waitHandles.CreationSemaphore.Release(1);
                                        }
                                    }
                                    else
                                    {
                                        // Timeout waiting for creation semaphore - return null
                                        connection = null;
                                        return(false);
                                    }
                                }
                            }
                            break;

                        default:
                            Interlocked.Decrement(ref _waitCount);
                            throw ADP.InternalError(ADP.InternalErrorCode.UnexpectedWaitAnyResult);
                        }
                    }
                    finally
                    {
                        if (CREATION_HANDLE == waitResult)
                        {
                            _waitHandles.CreationSemaphore.Release();
                        }
                    }
                } while (null == obj);
            }

            if (null != obj)
            {
                PrepareConnection(owningObject, obj);
            }

            connection = obj;
            return(true);
        }