Exemple #1
0
        //
        // Pool Insert/Delete methods
        //

        public void PutNewConnection(SqlInternalConnection con)
        {
            con.InPool = true; // mark as back in pool
            _stackNew.Push(con);
            _poolCounter.Modify(cAddFree);
            SafeNativeMethods.ReleaseSemaphore(_waitHandles[SEMAPHORE_HANDLE].Handle, 1, 0);
        }
            internal void InitPool()
            {
                try
                {
                    if (this.minItems > 0)
                    {
                        for (int i = 0; i < this.minItems; i++)
                        {
                            try
                            {
                                _freeItems.Push(CreateSocket());
                            }
                            catch (Exception ex)
                            {
                                _logger.LogError(ex, $"Failed to put {nameof(PooledSocket)} {i} in Pool");
                            }

                            // cannot connect to the server
                            if (!this.isAlive)
                            {
                                break;
                            }
                        }
                    }

                    if (_logger.IsEnabled(LogLevel.Debug))
                    {
                        _logger.LogDebug("Pool has been inited for {0} with {1} sockets", _endPoint, this.minItems);
                    }
                }
                catch (Exception e)
                {
                    _logger.LogError("Could not init pool.", new EventId(0), e);

                    this.MarkAsDead();
                }
            }
Exemple #3
0
        // Called when the cleanup-timer ticks over.
        private void CleanupCallback(Object state)
        {
            // This is the automatic prunning method.  Every period, we will perform a two-step
            // process.  First, for the connections above MinPool, we will obtain the semaphore for
            // the connection and then destroy it if it was on the old stack.  We will
            // continue this until we either reach MinPool size, or we are unable to obtain a free
            // connection, or until we have exhausted all the connections on the old stack.  After
            // that, push all connections on the new stack to the old stack.  So, every period
            // the connections on the old stack are destroyed and the connections on the new stack
            // are pushed to the old stack.  All connections that are currently out and in use are
            // not on either stack.  With this logic, a connection is prunned if unused for at least
            // one period but not more than two periods.

            // Destroy free connections above MinPool size from old stack.
            while (_poolCounter.TotalCount > _ctrl.MinPool)
            {
                // While above MinPoolSize...

                if (_waitHandles[SEMAPHORE_HANDLE].WaitOne(0, false) /* != WAIT_TIMEOUT */)
                {
                    // We obtained a connection from the semaphore.
                    SqlInternalConnection con = (SqlInternalConnection)_stackOld.Pop();

                    if (con != null)
                    {
                        // If we obtained one from the old stack, destroy it.
                        _poolCounter.Modify(-cAddFree);
                        DestroyConnection(con);
                    }
                    else
                    {
                        // Else we exhausted the old stack, so break.
                        SafeNativeMethods.ReleaseSemaphore(_waitHandles[SEMAPHORE_HANDLE].Handle, 1, 0);
                        break;
                    }
                }
                else
                {
                    break;
                }
            }

            // Push to the old-stack.  For each free connection, move connection from new stack
            // to old stack.
            if (_waitHandles[SEMAPHORE_HANDLE].WaitOne(0, false) /* != WAIT_TIMEOUT */)
            {
                for (;;)
                {
                    SqlInternalConnection con = (SqlInternalConnection)_stackNew.Pop();
                    if (con == null)
                    {
                        break;
                    }

                    _stackOld.Push(con);
                }
                SafeNativeMethods.ReleaseSemaphore(_waitHandles[SEMAPHORE_HANDLE].Handle, 1, 0);
            }

            // Make sure we're at quota by posting a callback to the threadpool.
            ThreadPool.QueueUserWorkItem(new WaitCallback(PoolCreateRequest));
        }