private RouteSpecificPool <T, C, E> GetPool(T route)
        {
            RouteSpecificPool <T, C, E> pool = this.routeToPool.Get(route);

            if (pool == null)
            {
                pool = new _RouteSpecificPool_146(this, route, route);
                this.routeToPool.Put(route, pool);
            }
            return(pool);
        }
 private void EnumEntries(IEnumerator <E> it, PoolEntryCallback <T, C> callback)
 {
     while (it.HasNext())
     {
         E entry = it.Next();
         callback.Process(entry);
         if (entry.IsClosed())
         {
             RouteSpecificPool <T, C, E> pool = GetPool(entry.GetRoute());
             pool.Remove(entry);
             it.Remove();
         }
     }
 }
        private void PurgePoolMap()
        {
            IEnumerator <KeyValuePair <T, RouteSpecificPool <T, C, E> > > it = this.routeToPool.EntrySet
                                                                                   ().GetEnumerator();

            while (it.HasNext())
            {
                KeyValuePair <T, RouteSpecificPool <T, C, E> > entry = it.Next();
                RouteSpecificPool <T, C, E> pool = entry.Value;
                if (pool.GetPendingCount() + pool.GetAllocatedCount() == 0)
                {
                    it.Remove();
                }
            }
        }
 public virtual PoolStats GetStats(T route)
 {
     Args.NotNull(route, "Route");
     this.Lock.Lock();
     try
     {
         RouteSpecificPool <T, C, E> pool = GetPool(route);
         return(new PoolStats(pool.GetLeasedCount(), pool.GetPendingCount(), pool.GetAvailableCount
                                  (), GetMax(route)));
     }
     finally
     {
         this.Lock.Unlock();
     }
 }
 public virtual void Release(E entry, bool reusable)
 {
     this.Lock.Lock();
     try
     {
         if (this.leased.Remove(entry))
         {
             RouteSpecificPool <T, C, E> pool = GetPool(entry.GetRoute());
             pool.Free(entry, reusable);
             if (reusable && !this.isShutDown)
             {
                 this.available.AddFirst(entry);
                 OnRelease(entry);
             }
             else
             {
                 entry.Close();
             }
             PoolEntryFuture <E> future = pool.NextPending();
             if (future != null)
             {
                 this.pending.Remove(future);
             }
             else
             {
                 future = this.pending.Poll();
             }
             if (future != null)
             {
                 future.Wakeup();
             }
         }
     }
     finally
     {
         this.Lock.Unlock();
     }
 }
        /// <exception cref="System.IO.IOException"></exception>
        /// <exception cref="System.Exception"></exception>
        /// <exception cref="Sharpen.TimeoutException"></exception>
        private E GetPoolEntryBlocking(T route, object state, long timeout, TimeUnit tunit
                                       , PoolEntryFuture <E> future)
        {
            DateTime deadline = null;

            if (timeout > 0)
            {
                deadline = Sharpen.Extensions.CreateDate(Runtime.CurrentTimeMillis() + tunit.ToMillis
                                                             (timeout));
            }
            this.Lock.Lock();
            try
            {
                RouteSpecificPool <T, C, E> pool = GetPool(route);
                E entry = null;
                while (entry == null)
                {
                    Asserts.Check(!this.isShutDown, "Connection pool shut down");
                    for (; ;)
                    {
                        entry = pool.GetFree(state);
                        if (entry == null)
                        {
                            break;
                        }
                        if (entry.IsClosed() || entry.IsExpired(Runtime.CurrentTimeMillis()))
                        {
                            entry.Close();
                            this.available.Remove(entry);
                            pool.Free(entry, false);
                        }
                        else
                        {
                            break;
                        }
                    }
                    if (entry != null)
                    {
                        this.available.Remove(entry);
                        this.leased.AddItem(entry);
                        return(entry);
                    }
                    // New connection is needed
                    int maxPerRoute = GetMax(route);
                    // Shrink the pool prior to allocating a new connection
                    int excess = Math.Max(0, pool.GetAllocatedCount() + 1 - maxPerRoute);
                    if (excess > 0)
                    {
                        for (int i = 0; i < excess; i++)
                        {
                            E lastUsed = pool.GetLastUsed();
                            if (lastUsed == null)
                            {
                                break;
                            }
                            lastUsed.Close();
                            this.available.Remove(lastUsed);
                            pool.Remove(lastUsed);
                        }
                    }
                    if (pool.GetAllocatedCount() < maxPerRoute)
                    {
                        int totalUsed    = this.leased.Count;
                        int freeCapacity = Math.Max(this.maxTotal - totalUsed, 0);
                        if (freeCapacity > 0)
                        {
                            int totalAvailable = this.available.Count;
                            if (totalAvailable > freeCapacity - 1)
                            {
                                if (!this.available.IsEmpty())
                                {
                                    E lastUsed = this.available.RemoveLast();
                                    lastUsed.Close();
                                    RouteSpecificPool <T, C, E> otherpool = GetPool(lastUsed.GetRoute());
                                    otherpool.Remove(lastUsed);
                                }
                            }
                            C conn = this.connFactory.Create(route);
                            entry = pool.Add(conn);
                            this.leased.AddItem(entry);
                            return(entry);
                        }
                    }
                    bool success = false;
                    try
                    {
                        pool.Queue(future);
                        this.pending.AddItem(future);
                        success = future.Await(deadline);
                    }
                    finally
                    {
                        // In case of 'success', we were woken up by the
                        // connection pool and should now have a connection
                        // waiting for us, or else we're shutting down.
                        // Just continue in the loop, both cases are checked.
                        pool.Unqueue(future);
                        this.pending.Remove(future);
                    }
                    // check for spurious wakeup vs. timeout
                    if (!success && (deadline != null) && (deadline.GetTime() <= Runtime.CurrentTimeMillis
                                                               ()))
                    {
                        break;
                    }
                }
                throw new TimeoutException("Timeout waiting for connection");
            }
            finally
            {
                this.Lock.Unlock();
            }
        }