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/AbstractConnPool.java $ 3069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * $Revision: 673450 $ 4069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * $Date: 2008-07-02 10:35:05 -0700 (Wed, 02 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.io.IOException; 34069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.lang.ref.Reference; 35069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.lang.ref.ReferenceQueue; 36069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.util.Set; 37069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.util.HashSet; 38069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.util.Iterator; 39069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.util.concurrent.TimeUnit; 40069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.util.concurrent.locks.Lock; 41069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.util.concurrent.locks.ReentrantLock; 42069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 43069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.commons.logging.Log; 44069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.commons.logging.LogFactory; 45069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.conn.ConnectionPoolTimeoutException; 46069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.conn.OperatedClientConnection; 47069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.conn.routing.HttpRoute; 48069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.http.impl.conn.IdleConnectionHandler; 49069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 50069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 51069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project/** 52069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * An abstract connection pool. 53069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * It is used by the {@link ThreadSafeClientConnManager}. 54069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The abstract pool includes a {@link #poolLock}, which is used to 55069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * synchronize access to the internal pool datastructures. 56069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Don't use <code>synchronized</code> for that purpose! 57d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath * 58d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath * @deprecated Please use {@link java.net.URL#openConnection} instead. 59d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath * Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a> 60d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath * for further details. 61069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 62d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath@Deprecated 63069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectpublic abstract class AbstractConnPool implements RefQueueHandler { 64069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 65069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private final Log log = LogFactory.getLog(getClass()); 66069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 67069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 68069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The global lock for this pool. 69069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 70069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected final Lock poolLock; 71069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 72069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 73069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 74069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * References to issued connections. 75069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Objects in this set are of class 76069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * {@link BasicPoolEntryRef BasicPoolEntryRef}, 77069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * and point to the pool entry for the issued connection. 78069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * GCed connections are detected by the missing pool entries. 79069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 80069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected Set<BasicPoolEntryRef> issuedConnections; 81069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 82069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** The handler for idle connections. */ 83069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected IdleConnectionHandler idleConnHandler; 84069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 85069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** The current total number of connections. */ 86069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected int numConnections; 87069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 88069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 89069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * A reference queue to track loss of pool entries to GC. 90069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The same queue is used to track loss of the connection manager, 91069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * so we cannot specialize the type. 92069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 93069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected ReferenceQueue<Object> refQueue; 94069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 95069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** A worker (thread) to track loss of pool entries to GC. */ 96069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private RefQueueWorker refWorker; 97069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 98069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 99069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** Indicates whether this pool is shut down. */ 100069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected volatile boolean isShutDown; 101069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 102069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 103069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Creates a new connection pool. 104069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 105069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected AbstractConnPool() { 106069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project issuedConnections = new HashSet<BasicPoolEntryRef>(); 107069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project idleConnHandler = new IdleConnectionHandler(); 108069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 109069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project boolean fair = false; //@@@ check parameters to decide 110069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project poolLock = new ReentrantLock(fair); 111069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 112069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 113069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 114069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 115069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Enables connection garbage collection (GC). 116069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This method must be called immediately after creating the 117069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * connection pool. It is not possible to enable connection GC 118069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * after pool entries have been created. Neither is it possible 119069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * to disable connection GC. 120069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 121069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @throws IllegalStateException 122069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * if connection GC is already enabled, or if it cannot be 123069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * enabled because there already are pool entries 124069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 125069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public void enableConnectionGC() 126069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throws IllegalStateException { 127069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 128069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (refQueue != null) { 129069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new IllegalStateException("Connection GC already enabled."); 130069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 131069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project poolLock.lock(); 132069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 133069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (numConnections > 0) { //@@@ is this check sufficient? 134069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new IllegalStateException("Pool already in use."); 135069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 136069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } finally { 137069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project poolLock.unlock(); 138069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 139069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 140069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project refQueue = new ReferenceQueue<Object>(); 141069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project refWorker = new RefQueueWorker(refQueue, this); 142069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Thread t = new Thread(refWorker); //@@@ use a thread factory 143069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project t.setDaemon(true); 144069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project t.setName("RefQueueWorker@" + this); 145069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project t.start(); 146069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 147069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 148069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 149069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 150069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Obtains a pool entry with a connection within the given timeout. 151069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 152069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param route the route for which to get the connection 153069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param timeout the timeout, 0 or negative for no timeout 154069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param tunit the unit for the <code>timeout</code>, 155069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * may be <code>null</code> only if there is no timeout 156069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 157069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return pool entry holding a connection for the route 158069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 159069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @throws ConnectionPoolTimeoutException 160069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * if the timeout expired 161069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @throws InterruptedException 162069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * if the calling thread was interrupted 163069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 164069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public final 165069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project BasicPoolEntry getEntry( 166069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project HttpRoute route, 167069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Object state, 168069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project long timeout, 169069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project TimeUnit tunit) 170069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throws ConnectionPoolTimeoutException, InterruptedException { 171069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return requestPoolEntry(route, state).getPoolEntry(timeout, tunit); 172069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 173069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 174069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 175069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Returns a new {@link PoolEntryRequest}, from which a {@link BasicPoolEntry} 176069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * can be obtained, or the request can be aborted. 177069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 178069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public abstract PoolEntryRequest requestPoolEntry(HttpRoute route, Object state); 179069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 180069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 181069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 182069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Returns an entry into the pool. 183069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The connection of the entry is expected to be in a suitable state, 184069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * either open and re-usable, or closed. The pool will not make any 185069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * attempt to determine whether it can be re-used or not. 186069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 187069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param entry the entry for the connection to release 188069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param reusable <code>true</code> if the entry is deemed 189069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * reusable, <code>false</code> otherwise. 190069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param validDuration The duration that the entry should remain free and reusable. 191069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param timeUnit The unit of time the duration is measured in. 192069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 193069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public abstract void freeEntry(BasicPoolEntry entry, boolean reusable, long validDuration, TimeUnit timeUnit) 194069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ; 195069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 196069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 197069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 198069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // non-javadoc, see interface RefQueueHandler 199069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project// BEGIN android-changed 200069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public void handleReference(Reference ref) { 201069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project// END android-changed 202069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project poolLock.lock(); 203069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 204069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 205069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (ref instanceof BasicPoolEntryRef) { 206069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // check if the GCed pool entry was still in use 207069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project //@@@ find a way to detect this without lookup 208069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project //@@@ flag in the BasicPoolEntryRef, to be reset when freed? 209069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project final boolean lost = issuedConnections.remove(ref); 210069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (lost) { 211069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project final HttpRoute route = 212069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ((BasicPoolEntryRef)ref).getRoute(); 213069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (log.isDebugEnabled()) { 214069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project log.debug("Connection garbage collected. " + route); 215069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 216069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project handleLostEntry(route); 217069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 218069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 219069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 220069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } finally { 221069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project poolLock.unlock(); 222069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 223069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 224069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 225069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 226069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 227069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Handles cleaning up for a lost pool entry with the given route. 228069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * A lost pool entry corresponds to a connection that was 229069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * garbage collected instead of being properly released. 230069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 231069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param route the route of the pool entry that was lost 232069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 233069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected abstract void handleLostEntry(HttpRoute route) 234069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ; 235069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 236069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 237069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 238069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Closes idle connections. 239069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 240069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param idletime the time the connections should have been idle 241069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * in order to be closed now 242069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param tunit the unit for the <code>idletime</code> 243069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 244069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public void closeIdleConnections(long idletime, TimeUnit tunit) { 245069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 246069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // idletime can be 0 or negative, no problem there 247069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (tunit == null) { 248069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new IllegalArgumentException("Time unit must not be null."); 249069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 250069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 251069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project poolLock.lock(); 252069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 253069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project idleConnHandler.closeIdleConnections(tunit.toMillis(idletime)); 254069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } finally { 255069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project poolLock.unlock(); 256069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 257069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 258069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 259069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public void closeExpiredConnections() { 260069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project poolLock.lock(); 261069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 262069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project idleConnHandler.closeExpiredConnections(); 263069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } finally { 264069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project poolLock.unlock(); 265069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 266069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 267069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 268069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 269069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project //@@@ revise this cleanup stuff (closeIdle+deleteClosed), it's not good 270069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 271069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 272069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Deletes all entries for closed connections. 273069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 274069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public abstract void deleteClosedConnections() 275069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ; 276069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 277069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 278069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 279069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Shuts down this pool and all associated resources. 280069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Overriding methods MUST call the implementation here! 281069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 282069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public void shutdown() { 283069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 284069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project poolLock.lock(); 285069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 286069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 287069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isShutDown) 288069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return; 289069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 290069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // no point in monitoring GC anymore 291069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (refWorker != null) 292069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project refWorker.shutdown(); 293069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 294069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // close all connections that are issued to an application 295069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Iterator<BasicPoolEntryRef> iter = issuedConnections.iterator(); 296069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project while (iter.hasNext()) { 297069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project BasicPoolEntryRef per = iter.next(); 298069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project iter.remove(); 299069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project BasicPoolEntry entry = per.get(); 300069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (entry != null) { 301069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project closeConnection(entry.getConnection()); 302069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 303069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 304069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 305069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // remove all references to connections 306069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project //@@@ use this for shutting them down instead? 307069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project idleConnHandler.removeAll(); 308069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 309069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project isShutDown = true; 310069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 311069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } finally { 312069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project poolLock.unlock(); 313069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 314069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 315069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 316069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 317069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 318069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Closes a connection from this pool. 319069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 320069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param conn the connection to close, or <code>null</code> 321069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 322069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected void closeConnection(final OperatedClientConnection conn) { 323069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (conn != null) { 324069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 325069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project conn.close(); 326069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (IOException ex) { 327069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project log.debug("I/O error closing connection", ex); 328069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 329069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 330069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 331069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 332069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 333069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 334069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 335069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 336069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project} // class AbstractConnPool 337069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 338