1069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project/*
2069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/ConnPoolByRoute.java $
3069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * $Revision: 677240 $
4069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * $Date: 2008-07-16 04:25:47 -0700 (Wed, 16 Jul 2008) $
5069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
6069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * ====================================================================
7069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
8069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
9069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
10069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *  this work for additional information regarding copyright ownership.
11069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
12069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *  (the "License"); you may not use this file except in compliance with
13069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *  the License.  You may obtain a copy of the License at
14069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
15069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
16069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
17069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
18069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
19069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *  See the License for the specific language governing permissions and
21069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *  limitations under the License.
22069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * ====================================================================
23069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
24069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This software consists of voluntary contributions made by many
25069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * individuals on behalf of the Apache Software Foundation.  For more
26069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * information on the Apache Software Foundation, please see
27069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <http://www.apache.org/>.
28069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
29069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */
30069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
31069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectpackage org.apache.http.impl.conn.tsccm;
32069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
33069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.util.Date;
34069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.util.HashMap;
35069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.util.Iterator;
36069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.util.Queue;
37069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.util.LinkedList;
38069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.util.Map;
39069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.util.concurrent.locks.Condition;
40069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.util.concurrent.TimeUnit;
41069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
42069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.commons.logging.Log;
43069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.commons.logging.LogFactory;
44069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.conn.routing.HttpRoute;
45069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.conn.ClientConnectionOperator;
46069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.conn.ConnectionPoolTimeoutException;
47069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.conn.params.ConnPerRoute;
48069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.conn.params.ConnManagerParams;
49069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.params.HttpParams;
50069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
51069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
52069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project/**
53069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * A connection pool that maintains connections by route.
54069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This class is derived from <code>MultiThreadedHttpConnectionManager</code>
55069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * in HttpClient 3.x, see there for original authors. It implements the same
56069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * algorithm for connection re-use and connection-per-host enforcement:
57069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <ul>
58069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <li>connections are re-used only for the exact same route</li>
59069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <li>connection limits are enforced per route rather than per host</li>
60069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * </ul>
61069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Note that access to the pool datastructures is synchronized via the
62069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * {@link AbstractConnPool#poolLock poolLock} in the base class,
63069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * not via <code>synchronized</code> methods.
64069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
65069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @author <a href="mailto:rolandw at apache.org">Roland Weber</a>
66069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @author <a href="mailto:becke@u.washington.edu">Michael Becke</a>
67069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @author and others
68069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */
69069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectpublic class ConnPoolByRoute extends AbstractConnPool {
70069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
71069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private final Log log = LogFactory.getLog(getClass());
72069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
73069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /** Connection operator for this pool */
74069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    protected final ClientConnectionOperator operator;
75069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
76069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /** The list of free connections */
77069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    protected Queue<BasicPoolEntry> freeConnections;
78069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
79069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /** The list of WaitingThreads waiting for a connection */
80069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    protected Queue<WaitingThread> waitingThreads;
81069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
82069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
83069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * A map of route-specific pools.
84069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Keys are of class {@link HttpRoute},
85069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * values of class {@link RouteSpecificPool}.
86069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
87069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    protected final Map<HttpRoute, RouteSpecificPool> routeToPool;
88069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
89069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    protected final int maxTotalConnections;
90069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
91069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private final ConnPerRoute connPerRoute;
92069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
93069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
94069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Creates a new connection pool, managed by route.
95069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
96069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public ConnPoolByRoute(final ClientConnectionOperator operator, final HttpParams params) {
97069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        super();
98069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (operator == null) {
99069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            throw new IllegalArgumentException("Connection operator may not be null");
100069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
101069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        this.operator = operator;
102069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
103069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        freeConnections = createFreeConnQueue();
104069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        waitingThreads  = createWaitingThreadQueue();
105069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        routeToPool     = createRouteToPoolMap();
106069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        maxTotalConnections = ConnManagerParams
107069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            .getMaxTotalConnections(params);
108069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        connPerRoute = ConnManagerParams
109069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            .getMaxConnectionsPerRoute(params);
110069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
111069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
112069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
113069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
114069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Creates the queue for {@link #freeConnections}.
115069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Called once by the constructor.
116069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
117069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return  a queue
118069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
119069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    protected Queue<BasicPoolEntry> createFreeConnQueue() {
120069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return new LinkedList<BasicPoolEntry>();
121069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
122069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
123069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
124069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Creates the queue for {@link #waitingThreads}.
125069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Called once by the constructor.
126069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
127069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return  a queue
128069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
129069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    protected Queue<WaitingThread> createWaitingThreadQueue() {
130069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return new LinkedList<WaitingThread>();
131069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
132069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
133069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
134069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Creates the map for {@link #routeToPool}.
135069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Called once by the constructor.
136069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
137069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return  a map
138069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
139069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    protected Map<HttpRoute, RouteSpecificPool> createRouteToPoolMap() {
140069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return new HashMap<HttpRoute, RouteSpecificPool>();
141069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
142069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
143069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
144069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
145069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Creates a new route-specific pool.
146069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Called by {@link #getRoutePool} when necessary.
147069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
148069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param route     the route
149069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
150069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return  the new pool
151069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
152069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    protected RouteSpecificPool newRouteSpecificPool(HttpRoute route) {
153069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return new RouteSpecificPool(route, connPerRoute.getMaxForRoute(route));
154069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
155069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
156069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
157069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
158069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Creates a new waiting thread.
159069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Called by {@link #getRoutePool} when necessary.
160069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
161069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param cond      the condition to wait for
162069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param rospl     the route specific pool, or <code>null</code>
163069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
164069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return  a waiting thread representation
165069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
166069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    protected WaitingThread newWaitingThread(Condition cond,
167069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                             RouteSpecificPool rospl) {
168069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return new WaitingThread(cond, rospl);
169069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
170069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
171069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
172069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
173069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Get a route-specific pool of available connections.
174069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
175069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param route   the route
176069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param create    whether to create the pool if it doesn't exist
177069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
178069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return  the pool for the argument route,
179069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *     never <code>null</code> if <code>create</code> is <code>true</code>
180069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
181069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    protected RouteSpecificPool getRoutePool(HttpRoute route,
182069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                             boolean create) {
183069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        RouteSpecificPool rospl = null;
184069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        poolLock.lock();
185069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        try {
186069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
187069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            rospl = routeToPool.get(route);
188069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if ((rospl == null) && create) {
189069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                // no pool for this route yet (or anymore)
190069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                rospl = newRouteSpecificPool(route);
191069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                routeToPool.put(route, rospl);
192069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
193069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
194069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } finally {
195069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            poolLock.unlock();
196069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
197069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
198069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return rospl;
199069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
200069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
201069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
202069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    //@@@ consider alternatives for gathering statistics
203069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public int getConnectionsInPool(HttpRoute route) {
204069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
205069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        poolLock.lock();
206069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        try {
207069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            // don't allow a pool to be created here!
208069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            RouteSpecificPool rospl = getRoutePool(route, false);
209069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return (rospl != null) ? rospl.getEntryCount() : 0;
210069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
211069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } finally {
212069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            poolLock.unlock();
213069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
214069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
215069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
216069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    @Override
217069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public PoolEntryRequest requestPoolEntry(
218069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            final HttpRoute route,
219069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            final Object state) {
220069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
221069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        final WaitingThreadAborter aborter = new WaitingThreadAborter();
222069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
223069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return new PoolEntryRequest() {
224069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
225069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            public void abortRequest() {
226069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                poolLock.lock();
227069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                try {
228069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    aborter.abort();
229069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                } finally {
230069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    poolLock.unlock();
231069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                }
232069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
233069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
234069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            public BasicPoolEntry getPoolEntry(
235069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    long timeout,
236069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    TimeUnit tunit)
237069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        throws InterruptedException, ConnectionPoolTimeoutException {
238069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                return getEntryBlocking(route, state, timeout, tunit, aborter);
239069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
240069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
241069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        };
242069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
243069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
244069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
245069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Obtains a pool entry with a connection within the given timeout.
246069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * If a {@link WaitingThread} is used to block, {@link WaitingThreadAborter#setWaitingThread(WaitingThread)}
247069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * must be called before blocking, to allow the thread to be interrupted.
248069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
249069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param route     the route for which to get the connection
250069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param timeout   the timeout, 0 or negative for no timeout
251069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param tunit     the unit for the <code>timeout</code>,
252069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  may be <code>null</code> only if there is no timeout
253069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param aborter   an object which can abort a {@link WaitingThread}.
254069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
255069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return  pool entry holding a connection for the route
256069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
257069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @throws ConnectionPoolTimeoutException
258069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *         if the timeout expired
259069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @throws InterruptedException
260069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *         if the calling thread was interrupted
261069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
262069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    protected BasicPoolEntry getEntryBlocking(
263069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                   HttpRoute route, Object state,
264069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                   long timeout, TimeUnit tunit,
265069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                   WaitingThreadAborter aborter)
266069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        throws ConnectionPoolTimeoutException, InterruptedException {
267069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
268069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        Date deadline = null;
269069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (timeout > 0) {
270069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            deadline = new Date
271069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                (System.currentTimeMillis() + tunit.toMillis(timeout));
272069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
273069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
274069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        BasicPoolEntry entry = null;
275069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        poolLock.lock();
276069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        try {
277069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
278069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            RouteSpecificPool rospl = getRoutePool(route, true);
279069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            WaitingThread waitingThread = null;
280069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
281069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            while (entry == null) {
282069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
283069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                if (isShutDown) {
284069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    throw new IllegalStateException
285069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        ("Connection pool shut down.");
286069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                }
287069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
288069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                if (log.isDebugEnabled()) {
289069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    log.debug("Total connections kept alive: " + freeConnections.size());
290069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    log.debug("Total issued connections: " + issuedConnections.size());
291069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    log.debug("Total allocated connection: " + numConnections + " out of " + maxTotalConnections);
292069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                }
293069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
294069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                // the cases to check for:
295069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                // - have a free connection for that route
296069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                // - allowed to create a free connection for that route
297069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                // - can delete and replace a free connection for another route
298069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                // - need to wait for one of the things above to come true
299069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
300069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                entry = getFreeEntry(rospl, state);
301069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                if (entry != null) {
302069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    break;
303069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                }
304069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
305069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                boolean hasCapacity = rospl.getCapacity() > 0;
306069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
307069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                if (log.isDebugEnabled()) {
308069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    log.debug("Available capacity: " + rospl.getCapacity()
309069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                            + " out of " + rospl.getMaxEntries()
310069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                            + " [" + route + "][" + state + "]");
311069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                }
312069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
313069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                if (hasCapacity && numConnections < maxTotalConnections) {
314069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
315069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    entry = createEntry(rospl, operator);
316069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
317069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                } else if (hasCapacity && !freeConnections.isEmpty()) {
318069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
319069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    deleteLeastUsedEntry();
320069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    entry = createEntry(rospl, operator);
321069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
322069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                } else {
323069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
324069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    if (log.isDebugEnabled()) {
325069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        log.debug("Need to wait for connection" +
326069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                " [" + route + "][" + state + "]");
327069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    }
328069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
329069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    if (waitingThread == null) {
330069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        waitingThread =
331069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                            newWaitingThread(poolLock.newCondition(), rospl);
332069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        aborter.setWaitingThread(waitingThread);
333069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    }
334069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
335069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    boolean success = false;
336069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    try {
337069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        rospl.queueThread(waitingThread);
338069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        waitingThreads.add(waitingThread);
339069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        success = waitingThread.await(deadline);
340069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
341069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    } finally {
342069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        // In case of 'success', we were woken up by the
343069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        // connection pool and should now have a connection
344069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        // waiting for us, or else we're shutting down.
345069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        // Just continue in the loop, both cases are checked.
346069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        rospl.removeThread(waitingThread);
347069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        waitingThreads.remove(waitingThread);
348069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    }
349069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
350069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    // check for spurious wakeup vs. timeout
351069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    if (!success && (deadline != null) &&
352069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        (deadline.getTime() <= System.currentTimeMillis())) {
353069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        throw new ConnectionPoolTimeoutException
354069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                            ("Timeout waiting for connection");
355069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    }
356069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                }
357069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } // while no entry
358069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
359069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } finally {
360069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            poolLock.unlock();
361069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
362069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
363069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return entry;
364069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
365069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    } // getEntry
366069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
367069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
368069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    // non-javadoc, see base class AbstractConnPool
369069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    @Override
370069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public void freeEntry(BasicPoolEntry entry, boolean reusable, long validDuration, TimeUnit timeUnit) {
371069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
372069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        HttpRoute route = entry.getPlannedRoute();
373069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (log.isDebugEnabled()) {
374069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            log.debug("Freeing connection" +
375069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    " [" + route + "][" + entry.getState() + "]");
376069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
377069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
378069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        poolLock.lock();
379069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        try {
380069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (isShutDown) {
381069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                // the pool is shut down, release the
382069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                // connection's resources and get out of here
383069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                closeConnection(entry.getConnection());
384069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                return;
385069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
386069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
387069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            // no longer issued, we keep a hard reference now
388069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            issuedConnections.remove(entry.getWeakRef());
389069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
390069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            RouteSpecificPool rospl = getRoutePool(route, true);
391069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
392069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (reusable) {
393069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                rospl.freeEntry(entry);
394069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                freeConnections.add(entry);
395069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                idleConnHandler.add(entry.getConnection(), validDuration, timeUnit);
396069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else {
397069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                rospl.dropEntry();
398069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                numConnections--;
399069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
400069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
401069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            notifyWaitingThread(rospl);
402069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
403069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } finally {
404069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            poolLock.unlock();
405069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
406069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
407069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    } // freeEntry
408069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
409069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
410069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
411069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
412069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * If available, get a free pool entry for a route.
413069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
414069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param rospl       the route-specific pool from which to get an entry
415069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
416069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return  an available pool entry for the given route, or
417069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *          <code>null</code> if none is available
418069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
419069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    protected BasicPoolEntry getFreeEntry(RouteSpecificPool rospl, Object state) {
420069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
421069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        BasicPoolEntry entry = null;
422069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        poolLock.lock();
423069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        try {
424069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            boolean done = false;
425069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            while(!done) {
426069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
427069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                entry = rospl.allocEntry(state);
428069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
429069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                if (entry != null) {
430069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    if (log.isDebugEnabled()) {
431069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        log.debug("Getting free connection"
432069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                + " [" + rospl.getRoute() + "][" + state + "]");
433069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
434069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    }
435069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    freeConnections.remove(entry);
436069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    boolean valid = idleConnHandler.remove(entry.getConnection());
437069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    if(!valid) {
438069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        // If the free entry isn't valid anymore, get rid of it
439069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        // and loop to find another one that might be valid.
440069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        if(log.isDebugEnabled())
441069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                            log.debug("Closing expired free connection"
442069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                    + " [" + rospl.getRoute() + "][" + state + "]");
443069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        closeConnection(entry.getConnection());
444069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        // We use dropEntry instead of deleteEntry because the entry
445069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        // is no longer "free" (we just allocated it), and deleteEntry
446069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        // can only be used to delete free entries.
447069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        rospl.dropEntry();
448069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        numConnections--;
449069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    } else {
450069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        issuedConnections.add(entry.getWeakRef());
451069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        done = true;
452069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    }
453069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
454069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                } else {
455069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    done = true;
456069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    if (log.isDebugEnabled()) {
457069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        log.debug("No free connections"
458069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                + " [" + rospl.getRoute() + "][" + state + "]");
459069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    }
460069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                }
461069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
462069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } finally {
463069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            poolLock.unlock();
464069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
465069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
466069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return entry;
467069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
468069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
469069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
470069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
471069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Creates a new pool entry.
472069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * This method assumes that the new connection will be handed
473069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * out immediately.
474069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
475069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param rospl       the route-specific pool for which to create the entry
476069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param op        the operator for creating a connection
477069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
478069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return  the new pool entry for a new connection
479069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
480069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    protected BasicPoolEntry createEntry(RouteSpecificPool rospl,
481069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                                         ClientConnectionOperator op) {
482069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
483069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (log.isDebugEnabled()) {
484069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            log.debug("Creating new connection [" + rospl.getRoute() + "]");
485069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
486069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
487069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        // the entry will create the connection when needed
488069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        BasicPoolEntry entry =
489069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            new BasicPoolEntry(op, rospl.getRoute(), refQueue);
490069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
491069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        poolLock.lock();
492069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        try {
493069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
494069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            rospl.createdEntry(entry);
495069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            numConnections++;
496069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
497069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            issuedConnections.add(entry.getWeakRef());
498069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
499069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } finally {
500069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            poolLock.unlock();
501069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
502069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
503069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return entry;
504069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
505069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
506069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
507069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
508069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Deletes a given pool entry.
509069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * This closes the pooled connection and removes all references,
510069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * so that it can be GCed.
511069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
512069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * <p><b>Note:</b> Does not remove the entry from the freeConnections list.
513069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * It is assumed that the caller has already handled this step.</p>
514069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * <!-- @@@ is that a good idea? or rather fix it? -->
515069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
516069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param entry         the pool entry for the connection to delete
517069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
518069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    protected void deleteEntry(BasicPoolEntry entry) {
519069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
520069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        HttpRoute route = entry.getPlannedRoute();
521069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
522069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (log.isDebugEnabled()) {
523069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            log.debug("Deleting connection"
524069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    + " [" + route + "][" + entry.getState() + "]");
525069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
526069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
527069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        poolLock.lock();
528069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        try {
529069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
530069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            closeConnection(entry.getConnection());
531069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
532069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            RouteSpecificPool rospl = getRoutePool(route, true);
533069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            rospl.deleteEntry(entry);
534069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            numConnections--;
535069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (rospl.isUnused()) {
536069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                routeToPool.remove(route);
537069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
538069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
539069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            idleConnHandler.remove(entry.getConnection());// not idle, but dead
540069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
541069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } finally {
542069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            poolLock.unlock();
543069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
544069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
545069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
546069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
547069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
548069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Delete an old, free pool entry to make room for a new one.
549069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Used to replace pool entries with ones for a different route.
550069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
551069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    protected void deleteLeastUsedEntry() {
552069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
553069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        try {
554069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            poolLock.lock();
555069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
556069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            //@@@ with get() instead of remove, we could
557069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            //@@@ leave the removing to deleteEntry()
558069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            BasicPoolEntry entry = freeConnections.remove();
559069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
560069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (entry != null) {
561069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                deleteEntry(entry);
562069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else if (log.isDebugEnabled()) {
563069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                log.debug("No free connection to delete.");
564069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
565069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
566069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } finally {
567069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            poolLock.unlock();
568069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
569069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
570069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
571069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
572069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    // non-javadoc, see base class AbstractConnPool
573069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    @Override
574069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    protected void handleLostEntry(HttpRoute route) {
575069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
576069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        poolLock.lock();
577069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        try {
578069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
579069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            RouteSpecificPool rospl = getRoutePool(route, true);
580069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            rospl.dropEntry();
581069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (rospl.isUnused()) {
582069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                routeToPool.remove(route);
583069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
584069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
585069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            numConnections--;
586069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            notifyWaitingThread(rospl);
587069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
588069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } finally {
589069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            poolLock.unlock();
590069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
591069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
592069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
593069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
594069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
595069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Notifies a waiting thread that a connection is available.
596069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * This will wake a thread waiting in the specific route pool,
597069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * if there is one.
598069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Otherwise, a thread in the connection pool will be notified.
599069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
600069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param rospl     the pool in which to notify, or <code>null</code>
601069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
602069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    protected void notifyWaitingThread(RouteSpecificPool rospl) {
603069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
604069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        //@@@ while this strategy provides for best connection re-use,
605069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        //@@@ is it fair? only do this if the connection is open?
606069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        // Find the thread we are going to notify. We want to ensure that
607069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        // each waiting thread is only interrupted once, so we will remove
608069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        // it from all wait queues before interrupting.
609069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        WaitingThread waitingThread = null;
610069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
611069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        poolLock.lock();
612069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        try {
613069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
614069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if ((rospl != null) && rospl.hasThread()) {
615069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                if (log.isDebugEnabled()) {
616069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    log.debug("Notifying thread waiting on pool" +
617069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                            " [" + rospl.getRoute() + "]");
618069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                }
619069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                waitingThread = rospl.nextThread();
620069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else if (!waitingThreads.isEmpty()) {
621069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                if (log.isDebugEnabled()) {
622069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    log.debug("Notifying thread waiting on any pool");
623069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                }
624069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                waitingThread = waitingThreads.remove();
625069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else if (log.isDebugEnabled()) {
626069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                log.debug("Notifying no-one, there are no waiting threads");
627069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
628069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
629069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (waitingThread != null) {
630069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                waitingThread.wakeup();
631069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
632069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
633069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } finally {
634069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            poolLock.unlock();
635069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
636069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
637069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
638069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
639069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    //@@@ revise this cleanup stuff
640069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    //@@@ move method to base class when deleteEntry() is fixed
641069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    // non-javadoc, see base class AbstractConnPool
642069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    @Override
643069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public void deleteClosedConnections() {
644069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
645069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        poolLock.lock();
646069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        try {
647069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
648069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            Iterator<BasicPoolEntry>  iter = freeConnections.iterator();
649069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            while (iter.hasNext()) {
650069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                BasicPoolEntry entry = iter.next();
651069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                if (!entry.getConnection().isOpen()) {
652069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    iter.remove();
653069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    deleteEntry(entry);
654069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                }
655069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
656069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
657069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } finally {
658069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            poolLock.unlock();
659069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
660069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
661069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
662069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
663069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    // non-javadoc, see base class AbstractConnPool
664069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    @Override
665069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public void shutdown() {
666069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
667069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        poolLock.lock();
668069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        try {
669069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
670069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            super.shutdown();
671069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
672069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            // close all free connections
673069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            //@@@ move this to base class?
674069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            Iterator<BasicPoolEntry> ibpe = freeConnections.iterator();
675069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            while (ibpe.hasNext()) {
676069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                BasicPoolEntry entry = ibpe.next();
677069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                ibpe.remove();
678069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                closeConnection(entry.getConnection());
679069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
680069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
681069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            // wake up all waiting threads
682069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            Iterator<WaitingThread> iwth = waitingThreads.iterator();
683069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            while (iwth.hasNext()) {
684069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                WaitingThread waiter = iwth.next();
685069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                iwth.remove();
686069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                waiter.wakeup();
687069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
688069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
689069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            routeToPool.clear();
690069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
691069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } finally {
692069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            poolLock.unlock();
693069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
694069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
695069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
696069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
697069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project} // class ConnPoolByRoute
698069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
699