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