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