Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 /*
2 * ====================================================================
3 *
4 * Licensed to the Apache Software Foundation (ASF) under one or more
5 * contributor license agreements. See the NOTICE file distributed with
6 * this work for additional information regarding copyright ownership.
7 * The ASF licenses this file to You under the Apache License, Version 2.0
8 * (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ====================================================================
19 *
20 * This software consists of voluntary contributions made by many
21 * individuals on behalf of the Apache Software Foundation. For more
22 * information on the Apache Software Foundation, please see
23 * <http://www.apache.org/>.
24 *
25 */
27 package ch.boye.httpclientandroidlib.impl.conn.tsccm;
29 import java.io.IOException;
30 import java.lang.ref.Reference;
31 import java.lang.ref.ReferenceQueue;
32 import java.util.Set;
33 import java.util.HashSet;
34 import java.util.Iterator;
35 import java.util.concurrent.TimeUnit;
36 import java.util.concurrent.locks.Lock;
37 import java.util.concurrent.locks.ReentrantLock;
39 import ch.boye.httpclientandroidlib.annotation.GuardedBy;
41 import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog;
42 /* LogFactory removed by HttpClient for Android script. */
43 import ch.boye.httpclientandroidlib.conn.ConnectionPoolTimeoutException;
44 import ch.boye.httpclientandroidlib.conn.OperatedClientConnection;
45 import ch.boye.httpclientandroidlib.conn.routing.HttpRoute;
46 import ch.boye.httpclientandroidlib.impl.conn.IdleConnectionHandler;
48 /**
49 * An abstract connection pool.
50 * It is used by the {@link ThreadSafeClientConnManager}.
51 * The abstract pool includes a {@link #poolLock}, which is used to
52 * synchronize access to the internal pool datastructures.
53 * Don't use <code>synchronized</code> for that purpose!
54 *
55 * @since 4.0
56 */
58 @Deprecated
59 public abstract class AbstractConnPool implements RefQueueHandler {
61 public HttpClientAndroidLog log;
63 /**
64 * The global lock for this pool.
65 */
66 protected final Lock poolLock;
68 /** References to issued connections */
69 @GuardedBy("poolLock")
70 protected Set<BasicPoolEntry> leasedConnections;
72 /** The current total number of connections. */
73 @GuardedBy("poolLock")
74 protected int numConnections;
76 /** Indicates whether this pool is shut down. */
77 protected volatile boolean isShutDown;
79 protected Set<BasicPoolEntryRef> issuedConnections;
81 protected ReferenceQueue<Object> refQueue;
83 protected IdleConnectionHandler idleConnHandler;
85 /**
86 * Creates a new connection pool.
87 */
88 protected AbstractConnPool() {
89 super();
90 this.log = new HttpClientAndroidLog(getClass());
91 this.leasedConnections = new HashSet<BasicPoolEntry>();
92 this.idleConnHandler = new IdleConnectionHandler();
93 this.poolLock = new ReentrantLock();
94 }
96 public void enableConnectionGC()
97 throws IllegalStateException {
98 }
100 /**
101 * Obtains a pool entry with a connection within the given timeout.
102 *
103 * @param route the route for which to get the connection
104 * @param timeout the timeout, 0 or negative for no timeout
105 * @param tunit the unit for the <code>timeout</code>,
106 * may be <code>null</code> only if there is no timeout
107 *
108 * @return pool entry holding a connection for the route
109 *
110 * @throws ConnectionPoolTimeoutException
111 * if the timeout expired
112 * @throws InterruptedException
113 * if the calling thread was interrupted
114 */
115 public final
116 BasicPoolEntry getEntry(
117 HttpRoute route,
118 Object state,
119 long timeout,
120 TimeUnit tunit)
121 throws ConnectionPoolTimeoutException, InterruptedException {
122 return requestPoolEntry(route, state).getPoolEntry(timeout, tunit);
123 }
125 /**
126 * Returns a new {@link PoolEntryRequest}, from which a {@link BasicPoolEntry}
127 * can be obtained, or the request can be aborted.
128 */
129 public abstract PoolEntryRequest requestPoolEntry(HttpRoute route, Object state);
132 /**
133 * Returns an entry into the pool.
134 * The connection of the entry is expected to be in a suitable state,
135 * either open and re-usable, or closed. The pool will not make any
136 * attempt to determine whether it can be re-used or not.
137 *
138 * @param entry the entry for the connection to release
139 * @param reusable <code>true</code> if the entry is deemed
140 * reusable, <code>false</code> otherwise.
141 * @param validDuration The duration that the entry should remain free and reusable.
142 * @param timeUnit The unit of time the duration is measured in.
143 */
144 public abstract void freeEntry(BasicPoolEntry entry, boolean reusable, long validDuration, TimeUnit timeUnit)
145 ;
147 public void handleReference(Reference<?> ref) {
148 }
150 protected abstract void handleLostEntry(HttpRoute route);
152 /**
153 * Closes idle connections.
154 *
155 * @param idletime the time the connections should have been idle
156 * in order to be closed now
157 * @param tunit the unit for the <code>idletime</code>
158 */
159 public void closeIdleConnections(long idletime, TimeUnit tunit) {
161 // idletime can be 0 or negative, no problem there
162 if (tunit == null) {
163 throw new IllegalArgumentException("Time unit must not be null.");
164 }
166 poolLock.lock();
167 try {
168 idleConnHandler.closeIdleConnections(tunit.toMillis(idletime));
169 } finally {
170 poolLock.unlock();
171 }
172 }
174 public void closeExpiredConnections() {
175 poolLock.lock();
176 try {
177 idleConnHandler.closeExpiredConnections();
178 } finally {
179 poolLock.unlock();
180 }
181 }
184 /**
185 * Deletes all entries for closed connections.
186 */
187 public abstract void deleteClosedConnections();
189 /**
190 * Shuts down this pool and all associated resources.
191 * Overriding methods MUST call the implementation here!
192 */
193 public void shutdown() {
195 poolLock.lock();
196 try {
198 if (isShutDown)
199 return;
201 // close all connections that are issued to an application
202 Iterator<BasicPoolEntry> iter = leasedConnections.iterator();
203 while (iter.hasNext()) {
204 BasicPoolEntry entry = iter.next();
205 iter.remove();
206 closeConnection(entry.getConnection());
207 }
208 idleConnHandler.removeAll();
210 isShutDown = true;
212 } finally {
213 poolLock.unlock();
214 }
215 }
218 /**
219 * Closes a connection from this pool.
220 *
221 * @param conn the connection to close, or <code>null</code>
222 */
223 protected void closeConnection(final OperatedClientConnection conn) {
224 if (conn != null) {
225 try {
226 conn.close();
227 } catch (IOException ex) {
228 log.debug("I/O error closing connection", ex);
229 }
230 }
231 }
233 } // class AbstractConnPool