FileDocCategorySizeDatePackage
AbstractConnPool.javaAPI DocAndroid 1.5 API10956Wed May 06 22:41:10 BST 2009org.apache.http.impl.conn.tsccm

AbstractConnPool

public abstract class AbstractConnPool extends Object implements RefQueueHandler
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 synchronized for that purpose!

Fields Summary
private final Log
log
protected final Lock
poolLock
The global lock for this pool.
protected Set
issuedConnections
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 IdleConnectionHandler
idleConnHandler
The handler for idle connections.
protected int
numConnections
The current total number of connections.
protected ReferenceQueue
refQueue
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.
private RefQueueWorker
refWorker
A worker (thread) to track loss of pool entries to GC.
protected volatile boolean
isShutDown
Indicates whether this pool is shut down.
Constructors Summary
protected AbstractConnPool()
Creates a new connection pool.


              
      
        issuedConnections = new HashSet<BasicPoolEntryRef>();
        idleConnHandler = new IdleConnectionHandler();

        boolean fair = false; //@@@ check parameters to decide
        poolLock = new ReentrantLock(fair);
    
Methods Summary
protected voidcloseConnection(org.apache.http.conn.OperatedClientConnection conn)
Closes a connection from this pool.

param
conn the connection to close, or null

        if (conn != null) {
            try {
                conn.close();
            } catch (IOException ex) {
                log.debug("I/O error closing connection", ex);
            }
        }
    
public voidcloseExpiredConnections()

        poolLock.lock();
        try {
            idleConnHandler.closeExpiredConnections();
        } finally {
            poolLock.unlock();
        }
    
public voidcloseIdleConnections(long idletime, java.util.concurrent.TimeUnit tunit)
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 idletime


        // 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 abstract voiddeleteClosedConnections()
Deletes all entries for closed connections.

public voidenableConnectionGC()
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


        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();
    
public abstract voidfreeEntry(org.apache.http.impl.conn.tsccm.BasicPoolEntry entry, boolean reusable, long validDuration, java.util.concurrent.TimeUnit timeUnit)
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 true if the entry is deemed reusable, false 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 final org.apache.http.impl.conn.tsccm.BasicPoolEntrygetEntry(org.apache.http.conn.routing.HttpRoute route, java.lang.Object state, long timeout, java.util.concurrent.TimeUnit tunit)
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 timeout, may be null 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

        return requestPoolEntry(route, state).getPoolEntry(timeout, tunit);
    
protected abstract voidhandleLostEntry(org.apache.http.conn.routing.HttpRoute route)
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

public voidhandleReference(java.lang.ref.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();
        }
    
public abstract org.apache.http.impl.conn.tsccm.PoolEntryRequestrequestPoolEntry(org.apache.http.conn.routing.HttpRoute route, java.lang.Object state)
Returns a new {@link PoolEntryRequest}, from which a {@link BasicPoolEntry} can be obtained, or the request can be aborted.

public voidshutdown()
Shuts down this pool and all associated resources. Overriding methods MUST call the implementation here!


        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();
        }