diff options
Diffstat (limited to 'src/org/apache/http/impl/conn/tsccm')
14 files changed, 0 insertions, 2583 deletions
diff --git a/src/org/apache/http/impl/conn/tsccm/AbstractConnPool.java b/src/org/apache/http/impl/conn/tsccm/AbstractConnPool.java deleted file mode 100644 index 2b37d72..0000000 --- a/src/org/apache/http/impl/conn/tsccm/AbstractConnPool.java +++ /dev/null @@ -1,332 +0,0 @@ -/* - * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/AbstractConnPool.java $ - * $Revision: 673450 $ - * $Date: 2008-07-02 10:35:05 -0700 (Wed, 02 Jul 2008) $ - * - * ==================================================================== - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. - * - */ - -package org.apache.http.impl.conn.tsccm; - -import java.io.IOException; -import java.lang.ref.Reference; -import java.lang.ref.ReferenceQueue; -import java.util.Set; -import java.util.HashSet; -import java.util.Iterator; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.http.conn.ConnectionPoolTimeoutException; -import org.apache.http.conn.OperatedClientConnection; -import org.apache.http.conn.routing.HttpRoute; -import org.apache.http.impl.conn.IdleConnectionHandler; - - -/** - * An abstract connection pool. - * It is used by the {@link ThreadSafeClientConnManager}. - * The abstract pool includes a {@link #poolLock}, which is used to - * synchronize access to the internal pool datastructures. - * Don't use <code>synchronized</code> for that purpose! - */ -public abstract class AbstractConnPool implements RefQueueHandler { - - private final Log log = LogFactory.getLog(getClass()); - - /** - * The global lock for this pool. - */ - protected final Lock poolLock; - - - /** - * References to issued connections. - * Objects in this set are of class - * {@link BasicPoolEntryRef BasicPoolEntryRef}, - * and point to the pool entry for the issued connection. - * GCed connections are detected by the missing pool entries. - */ - protected Set<BasicPoolEntryRef> issuedConnections; - - /** The handler for idle connections. */ - protected IdleConnectionHandler idleConnHandler; - - /** The current total number of connections. */ - protected int numConnections; - - /** - * A reference queue to track loss of pool entries to GC. - * The same queue is used to track loss of the connection manager, - * so we cannot specialize the type. - */ - protected ReferenceQueue<Object> refQueue; - - /** A worker (thread) to track loss of pool entries to GC. */ - private RefQueueWorker refWorker; - - - /** Indicates whether this pool is shut down. */ - protected volatile boolean isShutDown; - - /** - * Creates a new connection pool. - */ - protected AbstractConnPool() { - issuedConnections = new HashSet<BasicPoolEntryRef>(); - idleConnHandler = new IdleConnectionHandler(); - - boolean fair = false; //@@@ check parameters to decide - poolLock = new ReentrantLock(fair); - } - - - /** - * Enables connection garbage collection (GC). - * This method must be called immediately after creating the - * connection pool. It is not possible to enable connection GC - * after pool entries have been created. Neither is it possible - * to disable connection GC. - * - * @throws IllegalStateException - * if connection GC is already enabled, or if it cannot be - * enabled because there already are pool entries - */ - public void enableConnectionGC() - throws IllegalStateException { - - if (refQueue != null) { - throw new IllegalStateException("Connection GC already enabled."); - } - poolLock.lock(); - try { - if (numConnections > 0) { //@@@ is this check sufficient? - throw new IllegalStateException("Pool already in use."); - } - } finally { - poolLock.unlock(); - } - - refQueue = new ReferenceQueue<Object>(); - refWorker = new RefQueueWorker(refQueue, this); - Thread t = new Thread(refWorker); //@@@ use a thread factory - t.setDaemon(true); - t.setName("RefQueueWorker@" + this); - t.start(); - } - - - /** - * Obtains a pool entry with a connection within the given timeout. - * - * @param route the route for which to get the connection - * @param timeout the timeout, 0 or negative for no timeout - * @param tunit the unit for the <code>timeout</code>, - * may be <code>null</code> only if there is no timeout - * - * @return pool entry holding a connection for the route - * - * @throws ConnectionPoolTimeoutException - * if the timeout expired - * @throws InterruptedException - * if the calling thread was interrupted - */ - public final - BasicPoolEntry getEntry( - HttpRoute route, - Object state, - long timeout, - TimeUnit tunit) - throws ConnectionPoolTimeoutException, InterruptedException { - return requestPoolEntry(route, state).getPoolEntry(timeout, tunit); - } - - /** - * Returns a new {@link PoolEntryRequest}, from which a {@link BasicPoolEntry} - * can be obtained, or the request can be aborted. - */ - public abstract PoolEntryRequest requestPoolEntry(HttpRoute route, Object state); - - - /** - * Returns an entry into the pool. - * The connection of the entry is expected to be in a suitable state, - * either open and re-usable, or closed. The pool will not make any - * attempt to determine whether it can be re-used or not. - * - * @param entry the entry for the connection to release - * @param reusable <code>true</code> if the entry is deemed - * reusable, <code>false</code> otherwise. - * @param validDuration The duration that the entry should remain free and reusable. - * @param timeUnit The unit of time the duration is measured in. - */ - public abstract void freeEntry(BasicPoolEntry entry, boolean reusable, long validDuration, TimeUnit timeUnit) - ; - - - - // non-javadoc, see interface RefQueueHandler -// BEGIN android-changed - public void handleReference(Reference ref) { -// END android-changed - poolLock.lock(); - try { - - if (ref instanceof BasicPoolEntryRef) { - // check if the GCed pool entry was still in use - //@@@ find a way to detect this without lookup - //@@@ flag in the BasicPoolEntryRef, to be reset when freed? - final boolean lost = issuedConnections.remove(ref); - if (lost) { - final HttpRoute route = - ((BasicPoolEntryRef)ref).getRoute(); - if (log.isDebugEnabled()) { - log.debug("Connection garbage collected. " + route); - } - handleLostEntry(route); - } - } - - } finally { - poolLock.unlock(); - } - } - - - /** - * Handles cleaning up for a lost pool entry with the given route. - * A lost pool entry corresponds to a connection that was - * garbage collected instead of being properly released. - * - * @param route the route of the pool entry that was lost - */ - protected abstract void handleLostEntry(HttpRoute route) - ; - - - /** - * Closes idle connections. - * - * @param idletime the time the connections should have been idle - * in order to be closed now - * @param tunit the unit for the <code>idletime</code> - */ - public void closeIdleConnections(long idletime, TimeUnit tunit) { - - // idletime can be 0 or negative, no problem there - if (tunit == null) { - throw new IllegalArgumentException("Time unit must not be null."); - } - - poolLock.lock(); - try { - idleConnHandler.closeIdleConnections(tunit.toMillis(idletime)); - } finally { - poolLock.unlock(); - } - } - - public void closeExpiredConnections() { - poolLock.lock(); - try { - idleConnHandler.closeExpiredConnections(); - } finally { - poolLock.unlock(); - } - } - - - //@@@ revise this cleanup stuff (closeIdle+deleteClosed), it's not good - - /** - * Deletes all entries for closed connections. - */ - public abstract void deleteClosedConnections() - ; - - - /** - * Shuts down this pool and all associated resources. - * Overriding methods MUST call the implementation here! - */ - public void shutdown() { - - poolLock.lock(); - try { - - if (isShutDown) - return; - - // no point in monitoring GC anymore - if (refWorker != null) - refWorker.shutdown(); - - // close all connections that are issued to an application - Iterator<BasicPoolEntryRef> iter = issuedConnections.iterator(); - while (iter.hasNext()) { - BasicPoolEntryRef per = iter.next(); - iter.remove(); - BasicPoolEntry entry = per.get(); - if (entry != null) { - closeConnection(entry.getConnection()); - } - } - - // remove all references to connections - //@@@ use this for shutting them down instead? - idleConnHandler.removeAll(); - - isShutDown = true; - - } finally { - poolLock.unlock(); - } - } - - - /** - * Closes a connection from this pool. - * - * @param conn the connection to close, or <code>null</code> - */ - protected void closeConnection(final OperatedClientConnection conn) { - if (conn != null) { - try { - conn.close(); - } catch (IOException ex) { - log.debug("I/O error closing connection", ex); - } - } - } - - - - - -} // class AbstractConnPool - diff --git a/src/org/apache/http/impl/conn/tsccm/BasicPoolEntry.java b/src/org/apache/http/impl/conn/tsccm/BasicPoolEntry.java deleted file mode 100644 index dded360..0000000 --- a/src/org/apache/http/impl/conn/tsccm/BasicPoolEntry.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/BasicPoolEntry.java $ - * $Revision: 652721 $ - * $Date: 2008-05-01 17:32:20 -0700 (Thu, 01 May 2008) $ - * - * ==================================================================== - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. - * - */ - -package org.apache.http.impl.conn.tsccm; - - -import java.lang.ref.ReferenceQueue; - -import org.apache.http.conn.OperatedClientConnection; -import org.apache.http.conn.ClientConnectionOperator; -import org.apache.http.conn.routing.HttpRoute; -import org.apache.http.impl.conn.AbstractPoolEntry; - - - -/** - * Basic implementation of a connection pool entry. - */ -public class BasicPoolEntry extends AbstractPoolEntry { - - /** - * A weak reference to <code>this</code> used to detect GC of entries. - * Pool entries can only be GCed when they are allocated by an application - * and therefore not referenced with a hard link in the manager. - */ - private final BasicPoolEntryRef reference; - - /** - * Creates a new pool entry. - * - * @param op the connection operator - * @param route the planned route for the connection - * @param queue the reference queue for tracking GC of this entry, - * or <code>null</code> - */ - public BasicPoolEntry(ClientConnectionOperator op, - HttpRoute route, - ReferenceQueue<Object> queue) { - super(op, route); - if (route == null) { - throw new IllegalArgumentException("HTTP route may not be null"); - } - this.reference = new BasicPoolEntryRef(this, queue); - } - - protected final OperatedClientConnection getConnection() { - return super.connection; - } - - protected final HttpRoute getPlannedRoute() { - return super.route; - } - - protected final BasicPoolEntryRef getWeakRef() { - return this.reference; - } - - -} // class BasicPoolEntry - - diff --git a/src/org/apache/http/impl/conn/tsccm/BasicPoolEntryRef.java b/src/org/apache/http/impl/conn/tsccm/BasicPoolEntryRef.java deleted file mode 100644 index 32df8a5..0000000 --- a/src/org/apache/http/impl/conn/tsccm/BasicPoolEntryRef.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/BasicPoolEntryRef.java $ - * $Revision: 674186 $ - * $Date: 2008-07-05 05:18:54 -0700 (Sat, 05 Jul 2008) $ - * - * ==================================================================== - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. - * - */ - -package org.apache.http.impl.conn.tsccm; - - -import java.lang.ref.WeakReference; -import java.lang.ref.ReferenceQueue; - -import org.apache.http.conn.routing.HttpRoute; - - - -/** - * A weak reference to a {@link BasicPoolEntry BasicPoolEntry}. - * This reference explicitly keeps the planned route, so the connection - * can be reclaimed if it is lost to garbage collection. - */ -public class BasicPoolEntryRef extends WeakReference<BasicPoolEntry> { - - /** The planned route of the entry. */ - private final HttpRoute route; - - - /** - * Creates a new reference to a pool entry. - * - * @param entry the pool entry, must not be <code>null</code> - * @param queue the reference queue, or <code>null</code> - */ - public BasicPoolEntryRef(BasicPoolEntry entry, - ReferenceQueue<Object> queue) { - super(entry, queue); - if (entry == null) { - throw new IllegalArgumentException - ("Pool entry must not be null."); - } - route = entry.getPlannedRoute(); - } - - - /** - * Obtain the planned route for the referenced entry. - * The planned route is still available, even if the entry is gone. - * - * @return the planned route - */ - public final HttpRoute getRoute() { - return this.route; - } - -} // class BasicPoolEntryRef - diff --git a/src/org/apache/http/impl/conn/tsccm/BasicPooledConnAdapter.java b/src/org/apache/http/impl/conn/tsccm/BasicPooledConnAdapter.java deleted file mode 100644 index 29455d0..0000000 --- a/src/org/apache/http/impl/conn/tsccm/BasicPooledConnAdapter.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/BasicPooledConnAdapter.java $ - * $Revision: 653214 $ - * $Date: 2008-05-04 07:12:13 -0700 (Sun, 04 May 2008) $ - * - * ==================================================================== - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. - * - */ - -package org.apache.http.impl.conn.tsccm; - - -import org.apache.http.conn.ClientConnectionManager; -import org.apache.http.impl.conn.AbstractPoolEntry; -import org.apache.http.impl.conn.AbstractPooledConnAdapter; - - - -/** - * A connection wrapper and callback handler. - * All connections given out by the manager are wrappers which - * can be {@link #detach detach}ed to prevent further use on release. - */ -public class BasicPooledConnAdapter extends AbstractPooledConnAdapter { - - /** - * Creates a new adapter. - * - * @param tsccm the connection manager - * @param entry the pool entry for the connection being wrapped - */ - protected BasicPooledConnAdapter(ThreadSafeClientConnManager tsccm, - AbstractPoolEntry entry) { - super(tsccm, entry); - markReusable(); - } - - - @Override - protected ClientConnectionManager getManager() { - // override needed only to make method visible in this package - return super.getManager(); - } - - - /** - * Obtains the pool entry. - * - * @return the pool entry, or <code>null</code> if detached - */ - protected AbstractPoolEntry getPoolEntry() { - return super.poolEntry; - } - - - // non-javadoc, see base class - @Override - protected void detach() { - // override needed only to make method visible in this package - super.detach(); - } -} diff --git a/src/org/apache/http/impl/conn/tsccm/ConnPoolByRoute.java b/src/org/apache/http/impl/conn/tsccm/ConnPoolByRoute.java deleted file mode 100644 index cf59129..0000000 --- a/src/org/apache/http/impl/conn/tsccm/ConnPoolByRoute.java +++ /dev/null @@ -1,698 +0,0 @@ -/* - * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/ConnPoolByRoute.java $ - * $Revision: 677240 $ - * $Date: 2008-07-16 04:25:47 -0700 (Wed, 16 Jul 2008) $ - * - * ==================================================================== - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. - * - */ - -package org.apache.http.impl.conn.tsccm; - -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Queue; -import java.util.LinkedList; -import java.util.Map; -import java.util.concurrent.locks.Condition; -import java.util.concurrent.TimeUnit; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.http.conn.routing.HttpRoute; -import org.apache.http.conn.ClientConnectionOperator; -import org.apache.http.conn.ConnectionPoolTimeoutException; -import org.apache.http.conn.params.ConnPerRoute; -import org.apache.http.conn.params.ConnManagerParams; -import org.apache.http.params.HttpParams; - - -/** - * A connection pool that maintains connections by route. - * This class is derived from <code>MultiThreadedHttpConnectionManager</code> - * in HttpClient 3.x, see there for original authors. It implements the same - * algorithm for connection re-use and connection-per-host enforcement: - * <ul> - * <li>connections are re-used only for the exact same route</li> - * <li>connection limits are enforced per route rather than per host</li> - * </ul> - * Note that access to the pool datastructures is synchronized via the - * {@link AbstractConnPool#poolLock poolLock} in the base class, - * not via <code>synchronized</code> methods. - * - * @author <a href="mailto:rolandw at apache.org">Roland Weber</a> - * @author <a href="mailto:becke@u.washington.edu">Michael Becke</a> - * @author and others - */ -public class ConnPoolByRoute extends AbstractConnPool { - - private final Log log = LogFactory.getLog(getClass()); - - /** Connection operator for this pool */ - protected final ClientConnectionOperator operator; - - /** The list of free connections */ - protected Queue<BasicPoolEntry> freeConnections; - - /** The list of WaitingThreads waiting for a connection */ - protected Queue<WaitingThread> waitingThreads; - - /** - * A map of route-specific pools. - * Keys are of class {@link HttpRoute}, - * values of class {@link RouteSpecificPool}. - */ - protected final Map<HttpRoute, RouteSpecificPool> routeToPool; - - protected final int maxTotalConnections; - - private final ConnPerRoute connPerRoute; - - /** - * Creates a new connection pool, managed by route. - */ - public ConnPoolByRoute(final ClientConnectionOperator operator, final HttpParams params) { - super(); - if (operator == null) { - throw new IllegalArgumentException("Connection operator may not be null"); - } - this.operator = operator; - - freeConnections = createFreeConnQueue(); - waitingThreads = createWaitingThreadQueue(); - routeToPool = createRouteToPoolMap(); - maxTotalConnections = ConnManagerParams - .getMaxTotalConnections(params); - connPerRoute = ConnManagerParams - .getMaxConnectionsPerRoute(params); - } - - - /** - * Creates the queue for {@link #freeConnections}. - * Called once by the constructor. - * - * @return a queue - */ - protected Queue<BasicPoolEntry> createFreeConnQueue() { - return new LinkedList<BasicPoolEntry>(); - } - - /** - * Creates the queue for {@link #waitingThreads}. - * Called once by the constructor. - * - * @return a queue - */ - protected Queue<WaitingThread> createWaitingThreadQueue() { - return new LinkedList<WaitingThread>(); - } - - /** - * Creates the map for {@link #routeToPool}. - * Called once by the constructor. - * - * @return a map - */ - protected Map<HttpRoute, RouteSpecificPool> createRouteToPoolMap() { - return new HashMap<HttpRoute, RouteSpecificPool>(); - } - - - /** - * Creates a new route-specific pool. - * Called by {@link #getRoutePool} when necessary. - * - * @param route the route - * - * @return the new pool - */ - protected RouteSpecificPool newRouteSpecificPool(HttpRoute route) { - return new RouteSpecificPool(route, connPerRoute.getMaxForRoute(route)); - } - - - /** - * Creates a new waiting thread. - * Called by {@link #getRoutePool} when necessary. - * - * @param cond the condition to wait for - * @param rospl the route specific pool, or <code>null</code> - * - * @return a waiting thread representation - */ - protected WaitingThread newWaitingThread(Condition cond, - RouteSpecificPool rospl) { - return new WaitingThread(cond, rospl); - } - - - /** - * Get a route-specific pool of available connections. - * - * @param route the route - * @param create whether to create the pool if it doesn't exist - * - * @return the pool for the argument route, - * never <code>null</code> if <code>create</code> is <code>true</code> - */ - protected RouteSpecificPool getRoutePool(HttpRoute route, - boolean create) { - RouteSpecificPool rospl = null; - poolLock.lock(); - try { - - rospl = routeToPool.get(route); - if ((rospl == null) && create) { - // no pool for this route yet (or anymore) - rospl = newRouteSpecificPool(route); - routeToPool.put(route, rospl); - } - - } finally { - poolLock.unlock(); - } - - return rospl; - } - - - //@@@ consider alternatives for gathering statistics - public int getConnectionsInPool(HttpRoute route) { - - poolLock.lock(); - try { - // don't allow a pool to be created here! - RouteSpecificPool rospl = getRoutePool(route, false); - return (rospl != null) ? rospl.getEntryCount() : 0; - - } finally { - poolLock.unlock(); - } - } - - @Override - public PoolEntryRequest requestPoolEntry( - final HttpRoute route, - final Object state) { - - final WaitingThreadAborter aborter = new WaitingThreadAborter(); - - return new PoolEntryRequest() { - - public void abortRequest() { - poolLock.lock(); - try { - aborter.abort(); - } finally { - poolLock.unlock(); - } - } - - public BasicPoolEntry getPoolEntry( - long timeout, - TimeUnit tunit) - throws InterruptedException, ConnectionPoolTimeoutException { - return getEntryBlocking(route, state, timeout, tunit, aborter); - } - - }; - } - - /** - * Obtains a pool entry with a connection within the given timeout. - * If a {@link WaitingThread} is used to block, {@link WaitingThreadAborter#setWaitingThread(WaitingThread)} - * must be called before blocking, to allow the thread to be interrupted. - * - * @param route the route for which to get the connection - * @param timeout the timeout, 0 or negative for no timeout - * @param tunit the unit for the <code>timeout</code>, - * may be <code>null</code> only if there is no timeout - * @param aborter an object which can abort a {@link WaitingThread}. - * - * @return pool entry holding a connection for the route - * - * @throws ConnectionPoolTimeoutException - * if the timeout expired - * @throws InterruptedException - * if the calling thread was interrupted - */ - protected BasicPoolEntry getEntryBlocking( - HttpRoute route, Object state, - long timeout, TimeUnit tunit, - WaitingThreadAborter aborter) - throws ConnectionPoolTimeoutException, InterruptedException { - - Date deadline = null; - if (timeout > 0) { - deadline = new Date - (System.currentTimeMillis() + tunit.toMillis(timeout)); - } - - BasicPoolEntry entry = null; - poolLock.lock(); - try { - - RouteSpecificPool rospl = getRoutePool(route, true); - WaitingThread waitingThread = null; - - while (entry == null) { - - if (isShutDown) { - throw new IllegalStateException - ("Connection pool shut down."); - } - - if (log.isDebugEnabled()) { - log.debug("Total connections kept alive: " + freeConnections.size()); - log.debug("Total issued connections: " + issuedConnections.size()); - log.debug("Total allocated connection: " + numConnections + " out of " + maxTotalConnections); - } - - // the cases to check for: - // - have a free connection for that route - // - allowed to create a free connection for that route - // - can delete and replace a free connection for another route - // - need to wait for one of the things above to come true - - entry = getFreeEntry(rospl, state); - if (entry != null) { - break; - } - - boolean hasCapacity = rospl.getCapacity() > 0; - - if (log.isDebugEnabled()) { - log.debug("Available capacity: " + rospl.getCapacity() - + " out of " + rospl.getMaxEntries() - + " [" + route + "][" + state + "]"); - } - - if (hasCapacity && numConnections < maxTotalConnections) { - - entry = createEntry(rospl, operator); - - } else if (hasCapacity && !freeConnections.isEmpty()) { - - deleteLeastUsedEntry(); - entry = createEntry(rospl, operator); - - } else { - - if (log.isDebugEnabled()) { - log.debug("Need to wait for connection" + - " [" + route + "][" + state + "]"); - } - - if (waitingThread == null) { - waitingThread = - newWaitingThread(poolLock.newCondition(), rospl); - aborter.setWaitingThread(waitingThread); - } - - boolean success = false; - try { - rospl.queueThread(waitingThread); - waitingThreads.add(waitingThread); - success = waitingThread.await(deadline); - - } finally { - // In case of 'success', we were woken up by the - // connection pool and should now have a connection - // waiting for us, or else we're shutting down. - // Just continue in the loop, both cases are checked. - rospl.removeThread(waitingThread); - waitingThreads.remove(waitingThread); - } - - // check for spurious wakeup vs. timeout - if (!success && (deadline != null) && - (deadline.getTime() <= System.currentTimeMillis())) { - throw new ConnectionPoolTimeoutException - ("Timeout waiting for connection"); - } - } - } // while no entry - - } finally { - poolLock.unlock(); - } - - return entry; - - } // getEntry - - - // non-javadoc, see base class AbstractConnPool - @Override - public void freeEntry(BasicPoolEntry entry, boolean reusable, long validDuration, TimeUnit timeUnit) { - - HttpRoute route = entry.getPlannedRoute(); - if (log.isDebugEnabled()) { - log.debug("Freeing connection" + - " [" + route + "][" + entry.getState() + "]"); - } - - poolLock.lock(); - try { - if (isShutDown) { - // the pool is shut down, release the - // connection's resources and get out of here - closeConnection(entry.getConnection()); - return; - } - - // no longer issued, we keep a hard reference now - issuedConnections.remove(entry.getWeakRef()); - - RouteSpecificPool rospl = getRoutePool(route, true); - - if (reusable) { - rospl.freeEntry(entry); - freeConnections.add(entry); - idleConnHandler.add(entry.getConnection(), validDuration, timeUnit); - } else { - rospl.dropEntry(); - numConnections--; - } - - notifyWaitingThread(rospl); - - } finally { - poolLock.unlock(); - } - - } // freeEntry - - - - /** - * If available, get a free pool entry for a route. - * - * @param rospl the route-specific pool from which to get an entry - * - * @return an available pool entry for the given route, or - * <code>null</code> if none is available - */ - protected BasicPoolEntry getFreeEntry(RouteSpecificPool rospl, Object state) { - - BasicPoolEntry entry = null; - poolLock.lock(); - try { - boolean done = false; - while(!done) { - - entry = rospl.allocEntry(state); - - if (entry != null) { - if (log.isDebugEnabled()) { - log.debug("Getting free connection" - + " [" + rospl.getRoute() + "][" + state + "]"); - - } - freeConnections.remove(entry); - boolean valid = idleConnHandler.remove(entry.getConnection()); - if(!valid) { - // If the free entry isn't valid anymore, get rid of it - // and loop to find another one that might be valid. - if(log.isDebugEnabled()) - log.debug("Closing expired free connection" - + " [" + rospl.getRoute() + "][" + state + "]"); - closeConnection(entry.getConnection()); - // We use dropEntry instead of deleteEntry because the entry - // is no longer "free" (we just allocated it), and deleteEntry - // can only be used to delete free entries. - rospl.dropEntry(); - numConnections--; - } else { - issuedConnections.add(entry.getWeakRef()); - done = true; - } - - } else { - done = true; - if (log.isDebugEnabled()) { - log.debug("No free connections" - + " [" + rospl.getRoute() + "][" + state + "]"); - } - } - } - } finally { - poolLock.unlock(); - } - - return entry; - } - - - /** - * Creates a new pool entry. - * This method assumes that the new connection will be handed - * out immediately. - * - * @param rospl the route-specific pool for which to create the entry - * @param op the operator for creating a connection - * - * @return the new pool entry for a new connection - */ - protected BasicPoolEntry createEntry(RouteSpecificPool rospl, - ClientConnectionOperator op) { - - if (log.isDebugEnabled()) { - log.debug("Creating new connection [" + rospl.getRoute() + "]"); - } - - // the entry will create the connection when needed - BasicPoolEntry entry = - new BasicPoolEntry(op, rospl.getRoute(), refQueue); - - poolLock.lock(); - try { - - rospl.createdEntry(entry); - numConnections++; - - issuedConnections.add(entry.getWeakRef()); - - } finally { - poolLock.unlock(); - } - - return entry; - } - - - /** - * Deletes a given pool entry. - * This closes the pooled connection and removes all references, - * so that it can be GCed. - * - * <p><b>Note:</b> Does not remove the entry from the freeConnections list. - * It is assumed that the caller has already handled this step.</p> - * <!-- @@@ is that a good idea? or rather fix it? --> - * - * @param entry the pool entry for the connection to delete - */ - protected void deleteEntry(BasicPoolEntry entry) { - - HttpRoute route = entry.getPlannedRoute(); - - if (log.isDebugEnabled()) { - log.debug("Deleting connection" - + " [" + route + "][" + entry.getState() + "]"); - } - - poolLock.lock(); - try { - - closeConnection(entry.getConnection()); - - RouteSpecificPool rospl = getRoutePool(route, true); - rospl.deleteEntry(entry); - numConnections--; - if (rospl.isUnused()) { - routeToPool.remove(route); - } - - idleConnHandler.remove(entry.getConnection());// not idle, but dead - - } finally { - poolLock.unlock(); - } - } - - - /** - * Delete an old, free pool entry to make room for a new one. - * Used to replace pool entries with ones for a different route. - */ - protected void deleteLeastUsedEntry() { - - try { - poolLock.lock(); - - //@@@ with get() instead of remove, we could - //@@@ leave the removing to deleteEntry() - BasicPoolEntry entry = freeConnections.remove(); - - if (entry != null) { - deleteEntry(entry); - } else if (log.isDebugEnabled()) { - log.debug("No free connection to delete."); - } - - } finally { - poolLock.unlock(); - } - } - - - // non-javadoc, see base class AbstractConnPool - @Override - protected void handleLostEntry(HttpRoute route) { - - poolLock.lock(); - try { - - RouteSpecificPool rospl = getRoutePool(route, true); - rospl.dropEntry(); - if (rospl.isUnused()) { - routeToPool.remove(route); - } - - numConnections--; - notifyWaitingThread(rospl); - - } finally { - poolLock.unlock(); - } - } - - - /** - * Notifies a waiting thread that a connection is available. - * This will wake a thread waiting in the specific route pool, - * if there is one. - * Otherwise, a thread in the connection pool will be notified. - * - * @param rospl the pool in which to notify, or <code>null</code> - */ - protected void notifyWaitingThread(RouteSpecificPool rospl) { - - //@@@ while this strategy provides for best connection re-use, - //@@@ is it fair? only do this if the connection is open? - // Find the thread we are going to notify. We want to ensure that - // each waiting thread is only interrupted once, so we will remove - // it from all wait queues before interrupting. - WaitingThread waitingThread = null; - - poolLock.lock(); - try { - - if ((rospl != null) && rospl.hasThread()) { - if (log.isDebugEnabled()) { - log.debug("Notifying thread waiting on pool" + - " [" + rospl.getRoute() + "]"); - } - waitingThread = rospl.nextThread(); - } else if (!waitingThreads.isEmpty()) { - if (log.isDebugEnabled()) { - log.debug("Notifying thread waiting on any pool"); - } - waitingThread = waitingThreads.remove(); - } else if (log.isDebugEnabled()) { - log.debug("Notifying no-one, there are no waiting threads"); - } - - if (waitingThread != null) { - waitingThread.wakeup(); - } - - } finally { - poolLock.unlock(); - } - } - - - //@@@ revise this cleanup stuff - //@@@ move method to base class when deleteEntry() is fixed - // non-javadoc, see base class AbstractConnPool - @Override - public void deleteClosedConnections() { - - poolLock.lock(); - try { - - Iterator<BasicPoolEntry> iter = freeConnections.iterator(); - while (iter.hasNext()) { - BasicPoolEntry entry = iter.next(); - if (!entry.getConnection().isOpen()) { - iter.remove(); - deleteEntry(entry); - } - } - - } finally { - poolLock.unlock(); - } - } - - - // non-javadoc, see base class AbstractConnPool - @Override - public void shutdown() { - - poolLock.lock(); - try { - - super.shutdown(); - - // close all free connections - //@@@ move this to base class? - Iterator<BasicPoolEntry> ibpe = freeConnections.iterator(); - while (ibpe.hasNext()) { - BasicPoolEntry entry = ibpe.next(); - ibpe.remove(); - closeConnection(entry.getConnection()); - } - - // wake up all waiting threads - Iterator<WaitingThread> iwth = waitingThreads.iterator(); - while (iwth.hasNext()) { - WaitingThread waiter = iwth.next(); - iwth.remove(); - waiter.wakeup(); - } - - routeToPool.clear(); - - } finally { - poolLock.unlock(); - } - } - - -} // class ConnPoolByRoute - diff --git a/src/org/apache/http/impl/conn/tsccm/PoolEntryRequest.java b/src/org/apache/http/impl/conn/tsccm/PoolEntryRequest.java deleted file mode 100644 index faf5e3b..0000000 --- a/src/org/apache/http/impl/conn/tsccm/PoolEntryRequest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/PoolEntryRequest.java $ - * $Revision: 652020 $ - * $Date: 2008-04-27 14:23:31 -0700 (Sun, 27 Apr 2008) $ - * - * ==================================================================== - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. - * - */ - -package org.apache.http.impl.conn.tsccm; - -import java.util.concurrent.TimeUnit; - -import org.apache.http.conn.ConnectionPoolTimeoutException; - -/** - * Encapsulates a request for a {@link BasicPoolEntry}. - */ -public interface PoolEntryRequest { - - /** - * Obtains a pool entry with a connection within the given timeout. - * If {@link #abortRequest()} is called before this completes - * an {@link InterruptedException} is thrown. - * - * @param timeout the timeout, 0 or negative for no timeout - * @param tunit the unit for the <code>timeout</code>, - * may be <code>null</code> only if there is no timeout - * - * @return pool entry holding a connection for the route - * - * @throws ConnectionPoolTimeoutException - * if the timeout expired - * @throws InterruptedException - * if the calling thread was interrupted or the request was aborted - */ - BasicPoolEntry getPoolEntry( - long timeout, - TimeUnit tunit) throws InterruptedException, ConnectionPoolTimeoutException; - - /** - * Aborts the active or next call to - * {@link #getPoolEntry(long, TimeUnit)}. - */ - void abortRequest(); - -} diff --git a/src/org/apache/http/impl/conn/tsccm/RefQueueHandler.java b/src/org/apache/http/impl/conn/tsccm/RefQueueHandler.java deleted file mode 100644 index 3af28cc..0000000 --- a/src/org/apache/http/impl/conn/tsccm/RefQueueHandler.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/RefQueueHandler.java $ - * $Revision: 603874 $ - * $Date: 2007-12-13 02:42:41 -0800 (Thu, 13 Dec 2007) $ - * - * ==================================================================== - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. - * - */ - -package org.apache.http.impl.conn.tsccm; - -import java.lang.ref.Reference; - - -/** - * Callback handler for {@link RefQueueWorker RefQueueWorker}. - */ -public interface RefQueueHandler { - - /** - * Invoked when a reference is found on the queue. - * - * @param ref the reference to handle - */ - public void handleReference(Reference<?> ref) - ; -} diff --git a/src/org/apache/http/impl/conn/tsccm/RefQueueWorker.java b/src/org/apache/http/impl/conn/tsccm/RefQueueWorker.java deleted file mode 100644 index 9ad5c77..0000000 --- a/src/org/apache/http/impl/conn/tsccm/RefQueueWorker.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/RefQueueWorker.java $ - * $Revision: 673450 $ - * $Date: 2008-07-02 10:35:05 -0700 (Wed, 02 Jul 2008) $ - * - * ==================================================================== - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. - * - */ - -package org.apache.http.impl.conn.tsccm; - -import java.lang.ref.Reference; -import java.lang.ref.ReferenceQueue; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - - - -/** - * A worker thread for processing queued references. - * {@link Reference Reference}s can be - * {@link ReferenceQueue queued} - * automatically by the garbage collector. - * If that feature is used, a daemon thread should be executing - * this worker. It will pick up the queued references and pass them - * on to a handler for appropriate processing. - */ -public class RefQueueWorker implements Runnable { - - private final Log log = LogFactory.getLog(getClass()); - - /** The reference queue to monitor. */ - protected final ReferenceQueue<?> refQueue; - - /** The handler for the references found. */ - protected final RefQueueHandler refHandler; - - - /** - * The thread executing this handler. - * This attribute is also used as a shutdown indicator. - */ - protected volatile Thread workerThread; - - - /** - * Instantiates a new worker to listen for lost connections. - * - * @param queue the queue on which to wait for references - * @param handler the handler to pass the references to - */ - public RefQueueWorker(ReferenceQueue<?> queue, RefQueueHandler handler) { - if (queue == null) { - throw new IllegalArgumentException("Queue must not be null."); - } - if (handler == null) { - throw new IllegalArgumentException("Handler must not be null."); - } - - refQueue = queue; - refHandler = handler; - } - - - /** - * The main loop of this worker. - * If initialization succeeds, this method will only return - * after {@link #shutdown shutdown()}. Only one thread can - * execute the main loop at any time. - */ - public void run() { - - if (this.workerThread == null) { - this.workerThread = Thread.currentThread(); - } - - while (this.workerThread == Thread.currentThread()) { - try { - // remove the next reference and process it - Reference<?> ref = refQueue.remove(); - refHandler.handleReference(ref); - } catch (InterruptedException e) { - //@@@ is logging really necessary? this here is the - //@@@ only reason for having a log in this class - if (log.isDebugEnabled()) { - log.debug(this.toString() + " interrupted", e); - } - } - } - } - - - /** - * Shuts down this worker. - * It can be re-started afterwards by another call to {@link #run run()}. - */ - public void shutdown() { - Thread wt = this.workerThread; - if (wt != null) { - this.workerThread = null; // indicate shutdown - wt.interrupt(); - } - } - - - /** - * Obtains a description of this worker. - * - * @return a descriptive string for this worker - */ - @Override - public String toString() { - return "RefQueueWorker::" + this.workerThread; - } - -} // class RefQueueWorker - diff --git a/src/org/apache/http/impl/conn/tsccm/RouteSpecificPool.java b/src/org/apache/http/impl/conn/tsccm/RouteSpecificPool.java deleted file mode 100644 index 5c63933..0000000 --- a/src/org/apache/http/impl/conn/tsccm/RouteSpecificPool.java +++ /dev/null @@ -1,301 +0,0 @@ -/* - * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/RouteSpecificPool.java $ - * $Revision: 677240 $ - * $Date: 2008-07-16 04:25:47 -0700 (Wed, 16 Jul 2008) $ - * - * ==================================================================== - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. - * - */ - -package org.apache.http.impl.conn.tsccm; - -import java.io.IOException; -import java.util.ListIterator; -import java.util.Queue; -import java.util.LinkedList; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.http.conn.OperatedClientConnection; -import org.apache.http.conn.routing.HttpRoute; -import org.apache.http.util.LangUtils; - - -/** - * A connection sub-pool for a specific route, used by {@link ConnPoolByRoute}. - * The methods in this class are unsynchronized. It is expected that the - * containing pool takes care of synchronization. - */ -public class RouteSpecificPool { - - private final Log log = LogFactory.getLog(getClass()); - - /** The route this pool is for. */ - protected final HttpRoute route; - - /** the maximum number of entries allowed for this pool */ - protected final int maxEntries; - - /** - * The list of free entries. - * This list is managed LIFO, to increase idle times and - * allow for closing connections that are not really needed. - */ - protected final LinkedList<BasicPoolEntry> freeEntries; - - /** The list of threads waiting for this pool. */ - protected final Queue<WaitingThread> waitingThreads; - - /** The number of created entries. */ - protected int numEntries; - - - /** - * Creates a new route-specific pool. - * - * @param route the route for which to pool - * @param maxEntries the maximum number of entries allowed for this pool - */ - public RouteSpecificPool(HttpRoute route, int maxEntries) { - this.route = route; - this.maxEntries = maxEntries; - this.freeEntries = new LinkedList<BasicPoolEntry>(); - this.waitingThreads = new LinkedList<WaitingThread>(); - this.numEntries = 0; - } - - - /** - * Obtains the route for which this pool is specific. - * - * @return the route - */ - public final HttpRoute getRoute() { - return route; - } - - - /** - * Obtains the maximum number of entries allowed for this pool. - * - * @return the max entry number - */ - public final int getMaxEntries() { - return maxEntries; - } - - - /** - * Indicates whether this pool is unused. - * A pool is unused if there is neither an entry nor a waiting thread. - * All entries count, not only the free but also the allocated ones. - * - * @return <code>true</code> if this pool is unused, - * <code>false</code> otherwise - */ - public boolean isUnused() { - return (numEntries < 1) && waitingThreads.isEmpty(); - } - - - /** - * Return remaining capacity of this pool - * - * @return capacity - */ - public int getCapacity() { - return maxEntries - numEntries; - } - - - /** - * Obtains the number of entries. - * This includes not only the free entries, but also those that - * have been created and are currently issued to an application. - * - * @return the number of entries for the route of this pool - */ - public final int getEntryCount() { - return numEntries; - } - - - /** - * Obtains a free entry from this pool, if one is available. - * - * @return an available pool entry, or <code>null</code> if there is none - */ - public BasicPoolEntry allocEntry(final Object state) { - if (!freeEntries.isEmpty()) { - ListIterator<BasicPoolEntry> it = freeEntries.listIterator(freeEntries.size()); - while (it.hasPrevious()) { - BasicPoolEntry entry = it.previous(); - if (LangUtils.equals(state, entry.getState())) { - it.remove(); - return entry; - } - } - } - if (!freeEntries.isEmpty()) { - BasicPoolEntry entry = freeEntries.remove(); - entry.setState(null); - OperatedClientConnection conn = entry.getConnection(); - try { - conn.close(); - } catch (IOException ex) { - log.debug("I/O error closing connection", ex); - } - return entry; - } - return null; - } - - - /** - * Returns an allocated entry to this pool. - * - * @param entry the entry obtained from {@link #allocEntry allocEntry} - * or presented to {@link #createdEntry createdEntry} - */ - public void freeEntry(BasicPoolEntry entry) { - - if (numEntries < 1) { - throw new IllegalStateException - ("No entry created for this pool. " + route); - } - if (numEntries <= freeEntries.size()) { - throw new IllegalStateException - ("No entry allocated from this pool. " + route); - } - freeEntries.add(entry); - } - - - /** - * Indicates creation of an entry for this pool. - * The entry will <i>not</i> be added to the list of free entries, - * it is only recognized as belonging to this pool now. It can then - * be passed to {@link #freeEntry freeEntry}. - * - * @param entry the entry that was created for this pool - */ - public void createdEntry(BasicPoolEntry entry) { - - if (!route.equals(entry.getPlannedRoute())) { - throw new IllegalArgumentException - ("Entry not planned for this pool." + - "\npool: " + route + - "\nplan: " + entry.getPlannedRoute()); - } - - numEntries++; - } - - - /** - * Deletes an entry from this pool. - * Only entries that are currently free in this pool can be deleted. - * Allocated entries can not be deleted. - * - * @param entry the entry to delete from this pool - * - * @return <code>true</code> if the entry was found and deleted, or - * <code>false</code> if the entry was not found - */ - public boolean deleteEntry(BasicPoolEntry entry) { - - final boolean found = freeEntries.remove(entry); - if (found) - numEntries--; - return found; - } - - - /** - * Forgets about an entry from this pool. - * This method is used to indicate that an entry - * {@link #allocEntry allocated} - * from this pool has been lost and will not be returned. - */ - public void dropEntry() { - if (numEntries < 1) { - throw new IllegalStateException - ("There is no entry that could be dropped."); - } - numEntries--; - } - - - /** - * Adds a waiting thread. - * This pool makes no attempt to match waiting threads with pool entries. - * It is the caller's responsibility to check that there is no entry - * before adding a waiting thread. - * - * @param wt the waiting thread - */ - public void queueThread(WaitingThread wt) { - if (wt == null) { - throw new IllegalArgumentException - ("Waiting thread must not be null."); - } - this.waitingThreads.add(wt); - } - - - /** - * Checks whether there is a waiting thread in this pool. - * - * @return <code>true</code> if there is a waiting thread, - * <code>false</code> otherwise - */ - public boolean hasThread() { - return !this.waitingThreads.isEmpty(); - } - - - /** - * Returns the next thread in the queue. - * - * @return a waiting thread, or <code>null</code> if there is none - */ - public WaitingThread nextThread() { - return this.waitingThreads.peek(); - } - - - /** - * Removes a waiting thread, if it is queued. - * - * @param wt the waiting thread - */ - public void removeThread(WaitingThread wt) { - if (wt == null) - return; - - this.waitingThreads.remove(wt); - } - - -} // class RouteSpecificPool diff --git a/src/org/apache/http/impl/conn/tsccm/ThreadSafeClientConnManager.java b/src/org/apache/http/impl/conn/tsccm/ThreadSafeClientConnManager.java deleted file mode 100644 index 0781e05..0000000 --- a/src/org/apache/http/impl/conn/tsccm/ThreadSafeClientConnManager.java +++ /dev/null @@ -1,282 +0,0 @@ -/* - * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/ThreadSafeClientConnManager.java $ - * $Revision: 673450 $ - * $Date: 2008-07-02 10:35:05 -0700 (Wed, 02 Jul 2008) $ - * - * ==================================================================== - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. - * - */ - -package org.apache.http.impl.conn.tsccm; - -import java.io.IOException; -import java.util.concurrent.TimeUnit; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.http.conn.routing.HttpRoute; -import org.apache.http.conn.scheme.SchemeRegistry; -import org.apache.http.conn.ClientConnectionManager; -import org.apache.http.conn.ClientConnectionOperator; -import org.apache.http.conn.ClientConnectionRequest; -import org.apache.http.conn.ConnectionPoolTimeoutException; -import org.apache.http.conn.ManagedClientConnection; -import org.apache.http.conn.OperatedClientConnection; -import org.apache.http.params.HttpParams; -import org.apache.http.impl.conn.DefaultClientConnectionOperator; - - - -/** - * Manages a pool of {@link OperatedClientConnection client connections}. - * <p> - * This class is derived from <code>MultiThreadedHttpConnectionManager</code> - * in HttpClient 3. See there for original authors. - * </p> - * - * @author <a href="mailto:rolandw at apache.org">Roland Weber</a> - * @author <a href="mailto:becke@u.washington.edu">Michael Becke</a> - * - * - * <!-- empty lines to avoid svn diff problems --> - * @version $Revision: 673450 $ $Date: 2008-07-02 10:35:05 -0700 (Wed, 02 Jul 2008) $ - * - * @since 4.0 - */ -public class ThreadSafeClientConnManager implements ClientConnectionManager { - - private final Log log = LogFactory.getLog(getClass()); - - /** The schemes supported by this connection manager. */ - protected SchemeRegistry schemeRegistry; - - /** The pool of connections being managed. */ - protected final AbstractConnPool connectionPool; - - /** The operator for opening and updating connections. */ - protected ClientConnectionOperator connOperator; - - - - /** - * Creates a new thread safe connection manager. - * - * @param params the parameters for this manager - * @param schreg the scheme registry, or - * <code>null</code> for the default registry - */ - public ThreadSafeClientConnManager(HttpParams params, - SchemeRegistry schreg) { - - if (params == null) { - throw new IllegalArgumentException("HTTP parameters may not be null"); - } - this.schemeRegistry = schreg; - this.connOperator = createConnectionOperator(schreg); - this.connectionPool = createConnectionPool(params); - - } // <constructor> - - - @Override - protected void finalize() throws Throwable { - shutdown(); - super.finalize(); - } - - - /** - * Hook for creating the connection pool. - * - * @return the connection pool to use - */ - protected AbstractConnPool createConnectionPool(final HttpParams params) { - - AbstractConnPool acp = new ConnPoolByRoute(connOperator, params); - boolean conngc = true; //@@@ check parameters to decide - if (conngc) { - acp.enableConnectionGC(); - } - return acp; - } - - - /** - * Hook for creating the connection operator. - * It is called by the constructor. - * Derived classes can override this method to change the - * instantiation of the operator. - * The default implementation here instantiates - * {@link DefaultClientConnectionOperator DefaultClientConnectionOperator}. - * - * @param schreg the scheme registry to use, or <code>null</code> - * - * @return the connection operator to use - */ - protected ClientConnectionOperator - createConnectionOperator(SchemeRegistry schreg) { - - return new DefaultClientConnectionOperator(schreg); - } - - - // non-javadoc, see interface ClientConnectionManager - public SchemeRegistry getSchemeRegistry() { - return this.schemeRegistry; - } - - - public ClientConnectionRequest requestConnection( - final HttpRoute route, - final Object state) { - - final PoolEntryRequest poolRequest = connectionPool.requestPoolEntry( - route, state); - - return new ClientConnectionRequest() { - - public void abortRequest() { - poolRequest.abortRequest(); - } - - public ManagedClientConnection getConnection( - long timeout, TimeUnit tunit) throws InterruptedException, - ConnectionPoolTimeoutException { - if (route == null) { - throw new IllegalArgumentException("Route may not be null."); - } - - if (log.isDebugEnabled()) { - log.debug("ThreadSafeClientConnManager.getConnection: " - + route + ", timeout = " + timeout); - } - - BasicPoolEntry entry = poolRequest.getPoolEntry(timeout, tunit); - return new BasicPooledConnAdapter(ThreadSafeClientConnManager.this, entry); - } - - }; - - } - - - // non-javadoc, see interface ClientConnectionManager - public void releaseConnection(ManagedClientConnection conn, long validDuration, TimeUnit timeUnit) { - - if (!(conn instanceof BasicPooledConnAdapter)) { - throw new IllegalArgumentException - ("Connection class mismatch, " + - "connection not obtained from this manager."); - } - BasicPooledConnAdapter hca = (BasicPooledConnAdapter) conn; - if ((hca.getPoolEntry() != null) && (hca.getManager() != this)) { - throw new IllegalArgumentException - ("Connection not obtained from this manager."); - } - - try { - // make sure that the response has been read completely - if (hca.isOpen() && !hca.isMarkedReusable()) { - if (log.isDebugEnabled()) { - log.debug - ("Released connection open but not marked reusable."); - } - // In MTHCM, there would be a call to - // SimpleHttpConnectionManager.finishLastResponse(conn); - // Consuming the response is handled outside in 4.0. - - // make sure this connection will not be re-used - // Shut down rather than close, we might have gotten here - // because of a shutdown trigger. - // Shutdown of the adapter also clears the tracked route. - hca.shutdown(); - } - } catch (IOException iox) { - //@@@ log as warning? let pass? - if (log.isDebugEnabled()) - log.debug("Exception shutting down released connection.", - iox); - } finally { - BasicPoolEntry entry = (BasicPoolEntry) hca.getPoolEntry(); - boolean reusable = hca.isMarkedReusable(); - hca.detach(); - if (entry != null) { - connectionPool.freeEntry(entry, reusable, validDuration, timeUnit); - } - } - } - - - // non-javadoc, see interface ClientConnectionManager - public void shutdown() { - connectionPool.shutdown(); - } - - - /** - * Gets the total number of pooled connections for the given route. - * This is the total number of connections that have been created and - * are still in use by this connection manager for the route. - * This value will not exceed the maximum number of connections per host. - * - * @param route the route in question - * - * @return the total number of pooled connections for that route - */ - public int getConnectionsInPool(HttpRoute route) { - return ((ConnPoolByRoute)connectionPool).getConnectionsInPool( - route); - } - - - /** - * Gets the total number of pooled connections. This is the total number of - * connections that have been created and are still in use by this connection - * manager. This value will not exceed the maximum number of connections - * in total. - * - * @return the total number of pooled connections - */ - public int getConnectionsInPool() { - synchronized (connectionPool) { - return connectionPool.numConnections; //@@@ - } - } - - - // non-javadoc, see interface ClientConnectionManager - public void closeIdleConnections(long idleTimeout, TimeUnit tunit) { - // combine these two in a single call? - connectionPool.closeIdleConnections(idleTimeout, tunit); - connectionPool.deleteClosedConnections(); - } - - public void closeExpiredConnections() { - connectionPool.closeExpiredConnections(); - connectionPool.deleteClosedConnections(); - } - - -} // class ThreadSafeClientConnManager - diff --git a/src/org/apache/http/impl/conn/tsccm/WaitingThread.java b/src/org/apache/http/impl/conn/tsccm/WaitingThread.java deleted file mode 100644 index a50e11f..0000000 --- a/src/org/apache/http/impl/conn/tsccm/WaitingThread.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/WaitingThread.java $ - * $Revision: 649217 $ - * $Date: 2008-04-17 11:32:32 -0700 (Thu, 17 Apr 2008) $ - * - * ==================================================================== - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. - * - */ - -package org.apache.http.impl.conn.tsccm; - - -import java.util.Date; -import java.util.concurrent.locks.Condition; - - -/** - * Represents a thread waiting for a connection. - * This class implements throwaway objects. It is instantiated whenever - * a thread needs to wait. Instances are not re-used, except if the - * waiting thread experiences a spurious wakeup and continues to wait. - * <br/> - * All methods assume external synchronization on the condition - * passed to the constructor. - * Instances of this class do <i>not</i> synchronize access! - * - * @author <a href="mailto:rolandw at apache.org">Roland Weber</a> - */ -public class WaitingThread { - - /** The condition on which the thread is waiting. */ - private final Condition cond; - - /** The route specific pool on which the thread is waiting. */ - //@@@ replace with generic pool interface - private final RouteSpecificPool pool; - - /** The thread that is waiting for an entry. */ - private Thread waiter; - - /** True if this was interrupted. */ - private boolean aborted; - - - /** - * Creates a new entry for a waiting thread. - * - * @param cond the condition for which to wait - * @param pool the pool on which the thread will be waiting, - * or <code>null</code> - */ - public WaitingThread(Condition cond, RouteSpecificPool pool) { - - if (cond == null) { - throw new IllegalArgumentException("Condition must not be null."); - } - - this.cond = cond; - this.pool = pool; - } - - - /** - * Obtains the condition. - * - * @return the condition on which to wait, never <code>null</code> - */ - public final Condition getCondition() { - // not synchronized - return this.cond; - } - - - /** - * Obtains the pool, if there is one. - * - * @return the pool on which a thread is or was waiting, - * or <code>null</code> - */ - public final RouteSpecificPool getPool() { - // not synchronized - return this.pool; - } - - - /** - * Obtains the thread, if there is one. - * - * @return the thread which is waiting, or <code>null</code> - */ - public final Thread getThread() { - // not synchronized - return this.waiter; - } - - - /** - * Blocks the calling thread. - * This method returns when the thread is notified or interrupted, - * if a timeout occurrs, or if there is a spurious wakeup. - * <br/> - * This method assumes external synchronization. - * - * @param deadline when to time out, or <code>null</code> for no timeout - * - * @return <code>true</code> if the condition was satisfied, - * <code>false</code> in case of a timeout. - * Typically, a call to {@link #wakeup} is used to indicate - * that the condition was satisfied. Since the condition is - * accessible outside, this cannot be guaranteed though. - * - * @throws InterruptedException if the waiting thread was interrupted - * - * @see #wakeup - */ - public boolean await(Date deadline) - throws InterruptedException { - - // This is only a sanity check. We cannot synchronize here, - // the lock would not be released on calling cond.await() below. - if (this.waiter != null) { - throw new IllegalStateException - ("A thread is already waiting on this object." + - "\ncaller: " + Thread.currentThread() + - "\nwaiter: " + this.waiter); - } - - if (aborted) - throw new InterruptedException("Operation interrupted"); - - this.waiter = Thread.currentThread(); - - boolean success = false; - try { - if (deadline != null) { - success = this.cond.awaitUntil(deadline); - } else { - this.cond.await(); - success = true; - } - if (aborted) - throw new InterruptedException("Operation interrupted"); - } finally { - this.waiter = null; - } - return success; - - } // await - - - /** - * Wakes up the waiting thread. - * <br/> - * This method assumes external synchronization. - */ - public void wakeup() { - - // If external synchronization and pooling works properly, - // this cannot happen. Just a sanity check. - if (this.waiter == null) { - throw new IllegalStateException - ("Nobody waiting on this object."); - } - - // One condition might be shared by several WaitingThread instances. - // It probably isn't, but just in case: wake all, not just one. - this.cond.signalAll(); - } - - public void interrupt() { - aborted = true; - this.cond.signalAll(); - } - - -} // class WaitingThread diff --git a/src/org/apache/http/impl/conn/tsccm/WaitingThreadAborter.java b/src/org/apache/http/impl/conn/tsccm/WaitingThreadAborter.java deleted file mode 100644 index 1844457..0000000 --- a/src/org/apache/http/impl/conn/tsccm/WaitingThreadAborter.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/WaitingThreadAborter.java $ - * $Revision: 649220 $ - * $Date: 2008-04-17 11:40:24 -0700 (Thu, 17 Apr 2008) $ - * - * ==================================================================== - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. - * - */ - -package org.apache.http.impl.conn.tsccm; - -/** A simple class that can interrupt a {@link WaitingThread}. */ -public class WaitingThreadAborter { - - private WaitingThread waitingThread; - private boolean aborted; - - /** - * If a waiting thread has been set, interrupts it. - */ - public void abort() { - aborted = true; - - if (waitingThread != null) - waitingThread.interrupt(); - - } - - /** - * Sets the waiting thread. If this has already been aborted, - * the waiting thread is immediately interrupted. - * - * @param waitingThread The thread to interrupt when aborting. - */ - public void setWaitingThread(WaitingThread waitingThread) { - this.waitingThread = waitingThread; - if (aborted) - waitingThread.interrupt(); - } - -} diff --git a/src/org/apache/http/impl/conn/tsccm/doc-files/tsccm-structure.png b/src/org/apache/http/impl/conn/tsccm/doc-files/tsccm-structure.png Binary files differdeleted file mode 100644 index 2e2820d..0000000 --- a/src/org/apache/http/impl/conn/tsccm/doc-files/tsccm-structure.png +++ /dev/null diff --git a/src/org/apache/http/impl/conn/tsccm/package.html b/src/org/apache/http/impl/conn/tsccm/package.html deleted file mode 100644 index 5aca5d4..0000000 --- a/src/org/apache/http/impl/conn/tsccm/package.html +++ /dev/null @@ -1,205 +0,0 @@ -<html> -<head> -<!-- -/* - * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/conn/tsccm/package.html $ - * $Revision: 653041 $ - * $Date: 2008-05-03 03:39:28 -0700 (Sat, 03 May 2008) $ - * - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. - * - */ ---> -</head> -<body> - -The implementation of a thread-safe client connection manager. - -<center> -<img src="doc-files/tsccm-structure.png" alt="Relation Diagram"/> -</center> - -<p> -The implementation is structured into three areas, as illustrated -by the diagram above. -Facing the application is the <i>Manager</i> (green), which internally -maintains a <i>Pool</i> (yellow) of connections and waiting threads. -Both Manager and Pool rely on <i>Operations</i> (cyan) to provide the -actual connections. -</p> -<p> -In order to allow connection garbage collection, it is -imperative that hard object references between the areas are -restricted to the relations indicated by arrows in the diagram: -</p> -<ul> -<li>Applications reference only the Manager objects.</li> -<li>Manager objects reference Pool objects, but not vice versa.</li> -<li>Operations objects do not reference either Manager or Pool objects.</li> -</ul> - -<p> -The following table shows a selection of classes and interfaces, -and their assignment to the three areas. -</p> -<center> -<table border="1"> -<colgroup> - <col width="50%"/> - <col width="50%"/> -</colgroup> - -<tr> -<td style="text-align: center; background-color: #00ff00;"> -{@link org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager} -</td> -<td style="text-align: center; background-color: #ffff00;"> -{@link org.apache.http.impl.conn.tsccm.AbstractConnPool} -</td> -</tr> - -<tr> -<td style="text-align: center; background-color: #00ff00;"> -{@link org.apache.http.impl.conn.tsccm.BasicPooledConnAdapter} -</td> -<td style="text-align: center; background-color: #ffff00;"> -{@link org.apache.http.impl.conn.tsccm.ConnPoolByRoute} -</td> -</tr> - -<!-- appears on both sides! --> - -<tr> -<td style="text-align: right; background-color: #00ff00;"> -{@link org.apache.http.impl.conn.tsccm.BasicPoolEntry} -</td> -<td style="text-align: left; background-color: #ffff00;"> -{@link org.apache.http.impl.conn.tsccm.BasicPoolEntry} -</td> -</tr> - -<!-- ====================== --> - -<tr style="border-width: 5px;"> -</tr> - -<tr> -<td colspan="2" style="text-align: center; background-color: #00ffff;"> -{@link org.apache.http.conn.ClientConnectionOperator} -</td> -</tr> - -<tr> -<td colspan="2" style="text-align: center; background-color: #00ffff;"> -{@link org.apache.http.conn.OperatedClientConnection} -</td> -</tr> - -</table> -</center> - -<p> -The Manager area has implementations for the connection management -interfaces {@link org.apache.http.conn.ClientConnectionManager} -and {@link org.apache.http.conn.ManagedClientConnection}. -The latter is an adapter from managed to operated connections, based on a -{@link org.apache.http.impl.conn.tsccm.BasicPoolEntry}. -<br/> -The Pool area shows an abstract pool class -{@link org.apache.http.impl.conn.tsccm.AbstractConnPool} -and a concrete implementation -{@link org.apache.http.impl.conn.tsccm.ConnPoolByRoute} -which uses the same basic algorithm as the -<code>MultiThreadedHttpConnectionManager</code> -in HttpClient 3.x. -A pool contains instances of -{@link org.apache.http.impl.conn.tsccm.BasicPoolEntry}. -Most other classes in this package also belong to the Pool area. -<br/> -In the Operations area, you will find only the interfaces for -operated connections as defined in the org.apache.http.conn package. -The connection manager will work with all correct implementations -of these interfaces. This package therefore does not define anything -specific to the Operations area. -</p> - -<p> -As you have surely noticed, the -{@link org.apache.http.impl.conn.tsccm.BasicPoolEntry} -appears in both the Manager and Pool areas. -This is where things get tricky for connection garbage collection. -<br/> -A connection pool may start a background thread to implement cleanup. -In that case, the connection pool will not be garbage collected until -it is shut down, since the background thread keeps a hard reference -to the pool. The pool itself keeps hard references to the pooled entries, -which in turn reference idle connections. Neither of these is subject -to garbage collection. -Only the shutdown of the pool will stop the background thread, -thereby enabling garbage collection of the pool objects. -<br/> -A pool entry that is passed to an application by means of a connection -adapter will move from the Pool area to the Manager area. When the -connection is released by the application, the manager returns the -entry back to the pool. With that step, the pool entry moves from -the Manager area back to the Pool area. -While the entry is in the Manager area, the pool MUST NOT keep a -hard reference to it. -</p> - -<p> -The purpose of connection garbage collection is to detect when an -application fails to return a connection. In order to achieve this, -the only hard reference to the pool entry in the Manager area is -in the connection wrapper. The manager will not keep a hard reference -to the connection wrapper either, since that wrapper is effectively -moving to the Application area. -If the application drops it's reference to the connection wrapper, -that wrapper will be garbage collected, and with it the pool entry. -<br/> -In order to detect garbage collection of pool entries handed out -to the application, the pool keeps a <i>weak reference</i> to the -entry. Instances of -{@link org.apache.http.impl.conn.tsccm.BasicPoolEntryRef} -combine the weak reference with information about the route for -which the pool entry was allocated. If one of these entry references -becomes stale, the pool can accommodate for the lost connection. -This is triggered either by a background thread waiting for the -references to be queued by the garbage collector, or by the -application calling a {@link - org.apache.http.conn.ClientConnectionManager#closeIdleConnections cleanup} -method of the connection manager. -<br/> -Basically the same trick is used for detecting garbage collection -of the connection manager itself. The pool keeps a weak reference -to the connection manager that created it. However, this will work -only if there is a background thread to detect when that reference -is queued by the garbage collector. Otherwise, a finalizer of the -connection manager will shut down the pool and release it's resources. -</p> - - -</body> -</html> |