mirror of
https://github.com/apache/httpcomponents-client.git
synced 2025-02-17 07:26:47 +00:00
HTTPCLIENT-636: a wee bit closer towards getting rid of static maps
git-svn-id: https://svn.apache.org/repos/asf/jakarta/httpcomponents/httpclient/trunk@558458 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
e7e4c61470
commit
bdeb8786af
@ -573,12 +573,11 @@ void shutdownCheckedOutConnections(ConnectionPool connectionPool) {
|
||||
// ------------------------------------------------------- Instance Methods
|
||||
|
||||
/**
|
||||
* Shuts down the connection manager and releases all resources. All connections associated
|
||||
* with this class will be closed and released.
|
||||
*
|
||||
* <p>The connection manager can no longer be used once shutdown.
|
||||
*
|
||||
* <p>Calling this method more than once will have no effect.
|
||||
* Shuts down the connection manager and releases all resources.
|
||||
* All connections associated with this manager will be closed
|
||||
* and released.
|
||||
* The connection manager can no longer be used once shut down.
|
||||
* Calling this method more than once will have no effect.
|
||||
*/
|
||||
public synchronized void shutdown() {
|
||||
synchronized (connectionPool) {
|
||||
@ -686,6 +685,10 @@ private class ConnectionPool {
|
||||
//@@@ this should be a pool-specific reference queue
|
||||
private ReferenceQueue refQueue = REFERENCE_QUEUE; //@@@
|
||||
|
||||
/** A worker (thread) to track loss of pool entries to GC. */
|
||||
private LostConnWorker refWorker;
|
||||
|
||||
|
||||
/**
|
||||
* Map of route-specific pools.
|
||||
* Keys are of class {@link HttpRoute}, and
|
||||
@ -693,11 +696,30 @@ private class ConnectionPool {
|
||||
*/
|
||||
private final Map mapRoutes = new HashMap();
|
||||
|
||||
private IdleConnectionHandler idleConnectionHandler = new IdleConnectionHandler();
|
||||
private IdleConnectionHandler idleConnectionHandler =
|
||||
new IdleConnectionHandler();
|
||||
|
||||
/** The number of created connections */
|
||||
private int numConnections = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new connection pool.
|
||||
*/
|
||||
private ConnectionPool() {
|
||||
//@@@ currently must be false, otherwise the TSCCM
|
||||
//@@@ will not be garbage collected in the unit test...
|
||||
boolean conngc = false; //@@@ check parameters to decide
|
||||
if (conngc) {
|
||||
refQueue = new ReferenceQueue();
|
||||
refWorker = new LostConnWorker(this);
|
||||
Thread t = new Thread(refWorker); //@@@ use a thread factory
|
||||
t.setDaemon(true);
|
||||
t.setName("LostConnWorker/"+ThreadSafeClientConnManager.this);
|
||||
t.start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up all connection pool resources.
|
||||
*/
|
||||
@ -710,7 +732,9 @@ public synchronized void shutdown() {
|
||||
iter.remove();
|
||||
closeConnection(entry.connection);
|
||||
}
|
||||
|
||||
|
||||
if (refWorker != null)
|
||||
refWorker.shutdown();
|
||||
// close all connections that have been checked out
|
||||
iter = issuedConnections.iterator();
|
||||
while (iter.hasNext()) {
|
||||
@ -771,6 +795,30 @@ TrackingPoolEntry createEntry(HttpRoute route,
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles cleaning up for the given connection reference.
|
||||
* Invoked by the worker listening for lost connections.
|
||||
*
|
||||
* @param ref the reference to clean up
|
||||
*/
|
||||
protected synchronized void handleReference(PoolEntryRef ref) {
|
||||
|
||||
// check if the GCed pool entry was still in use
|
||||
//@@@ find a way to detect this without lookup
|
||||
//@@@ flag in the PoolEntryRef, to be reset when freed?
|
||||
final boolean lost = issuedConnections.remove(ref);
|
||||
if (lost) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(
|
||||
"Connection reclaimed by garbage collector. "
|
||||
+ ref.route);
|
||||
}
|
||||
|
||||
handleLostConnection(ref.route);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles cleaning up for a lost connection with the given config.
|
||||
@ -779,7 +827,7 @@ TrackingPoolEntry createEntry(HttpRoute route,
|
||||
*
|
||||
* @param config the route of the connection that was lost
|
||||
*/
|
||||
public synchronized
|
||||
private synchronized
|
||||
void handleLostConnection(HttpRoute route) {
|
||||
|
||||
RouteConnPool routePool = getRoutePool(route);
|
||||
@ -1159,6 +1207,69 @@ public void run() {
|
||||
} // class ReferenceQueueThread
|
||||
|
||||
|
||||
/**
|
||||
* Tracker for GCed connections.
|
||||
* Can be started in a background thread.
|
||||
* The worker will listen on a {@link ReferenceQueue ReferenceQueue}
|
||||
* for {@link PoolEntryRef PoolEntryRef} objects being queued.
|
||||
*/
|
||||
private static class LostConnWorker implements Runnable {
|
||||
|
||||
private volatile Thread workerThread;
|
||||
|
||||
private final ConnectionPool connPool;
|
||||
|
||||
|
||||
/**
|
||||
* Instantiates a new worker to listen for lost connections.
|
||||
*
|
||||
* @param pool the connection pool for which to work,
|
||||
* and in which to reclaim the lost connections
|
||||
*/
|
||||
public LostConnWorker(ConnectionPool pool) {
|
||||
this.connPool = pool;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Shuts down this worker.
|
||||
*/
|
||||
public void shutdown() {
|
||||
Thread wt = this.workerThread;
|
||||
if (wt != null) {
|
||||
this.workerThread = null; // indicate shutdown
|
||||
wt.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 = connPool.refQueue.remove();
|
||||
if (ref instanceof PoolEntryRef) {
|
||||
connPool.handleReference((PoolEntryRef) ref);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
LOG.debug("LostConnWorker interrupted", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // class ReferenceQueueThread
|
||||
|
||||
|
||||
/**
|
||||
* A weak reference to a pool entry.
|
||||
* Needed for connection GC.
|
||||
|
Loading…
x
Reference in New Issue
Block a user