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