Index: src/java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java =================================================================== retrieving revision 1.39 diff -u -r1.39 MultiThreadedHttpConnectionManager.java --- src/java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java 13 May 2004 04:03:25 -0000 1.39 +++ src/java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java 4 Jun 2004 01:44:02 -0000 @@ -527,30 +527,72 @@ } /** + * Gets the total number of pooled connections for the given host configuration. This + * is the total number of connections that have been created and are still in use + * by this connection manager for the host configuration. This value will + * not exceed the {@link #getMaxConnectionsPerHost() maximum number of connections per + * host}. + * + * @param hostConfiguration The host configuration + * @return The total number of pooled connections + */ + public int getConnectionsInPool(HostConfiguration hostConfiguration) { + synchronized (connectionPool) { + HostConnectionPool hostPool = connectionPool.getHostPool(hostConfiguration); + return hostPool.numConnections; + } + } + + /** + * 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 {@link #getMaxTotalConnections() + * maximum number of connections}. + * + * @return the total number of pooled connections + */ + public int getConnectionsInPool() { + synchronized (connectionPool) { + return connectionPool.numConnections; + } + } + + /** * Gets the number of connections in use for this configuration. * * @param hostConfiguration the key that connections are tracked on * @return the number of connections in use + * + * @deprecated Use {@link #getConnectionsInPool(HostConfiguration)} */ public int getConnectionsInUse(HostConfiguration hostConfiguration) { - synchronized (connectionPool) { - HostConnectionPool hostPool = connectionPool.getHostPool(hostConfiguration); - return hostPool.numConnections; - } + return getConnectionsInPool(hostConfiguration); } /** * Gets the total number of connections in use. * * @return the total number of connections in use + * + * @deprecated Use {@link #getConnectionsInPool()} */ public int getConnectionsInUse() { - synchronized (connectionPool) { - return connectionPool.numConnections; - } + return getConnectionsInPool(); } /** + * Deletes all closed connections. Only connections currently owned by the connection + * manager are processed. + * + * @see HttpConnection#isOpen() + * + * @since 3.0 + */ + public void deleteClosedConnections() { + connectionPool.deleteClosedConnections(); + } + + /** * @since 3.0 */ public void closeIdleConnections(long idleTimeout) { @@ -794,6 +836,22 @@ } return connection; } + + /** + * Deletes all closed connections. + */ + public synchronized void deleteClosedConnections() { + + Iterator iter = freeConnections.iterator(); + + while (iter.hasNext()) { + HttpConnection conn = (HttpConnection) iter.next(); + if (!conn.isOpen()) { + iter.remove(); + deleteConnection(conn); + } + } + } /** * Closes idle connections. @@ -804,31 +862,43 @@ } /** - * Close and delete an old, unused connection to make room for a new one. + * Deletes the given connection. This will remove all reference to the connection + * so that it can be GCed. + * + *
Note: Does not remove the connection from the freeConnections list. It + * is assumed that the caller has already handled this case.
+ * + * @param connection The connection to delete */ - public synchronized void deleteLeastUsedConnection() { + private synchronized void deleteConnection(HttpConnection connection) { + + HostConfiguration connectionConfiguration = configurationForConnection(connection); - HttpConnection connection = (HttpConnection) freeConnections.removeFirst(); + if (LOG.isDebugEnabled()) { + LOG.debug("Reclaiming connection, hostConfig=" + connectionConfiguration); + } - if (connection != null) { - HostConfiguration connectionConfiguration = configurationForConnection(connection); + connection.close(); - if (LOG.isDebugEnabled()) { - LOG.debug("Reclaiming unused connection, hostConfig=" - + connectionConfiguration); - } + HostConnectionPool hostPool = getHostPool(connectionConfiguration); + + hostPool.freeConnections.remove(connection); + hostPool.numConnections--; + numConnections--; - connection.close(); + // remove the connection from the timeout handler + idleConnectionHandler.remove(connection); + } + + /** + * Close and delete an old, unused connection to make room for a new one. + */ + public synchronized void deleteLeastUsedConnection() { - HostConnectionPool hostPool = getHostPool(connectionConfiguration); - - hostPool.freeConnections.remove(connection); - hostPool.numConnections--; - numConnections--; + HttpConnection connection = (HttpConnection) freeConnections.removeFirst(); - // remove the connection from the timeout handler - idleConnectionHandler.remove(connection); - + if (connection != null) { + deleteConnection(connection); } else if (LOG.isDebugEnabled()) { LOG.debug("Attempted to reclaim an unused connection but there were none."); } Index: src/test/org/apache/commons/httpclient/TestHttpConnectionManager.java =================================================================== retrieving revision 1.21 diff -u -r1.21 TestHttpConnectionManager.java --- src/test/org/apache/commons/httpclient/TestHttpConnectionManager.java 13 Apr 2004 21:47:29 -0000 1.21 +++ src/test/org/apache/commons/httpclient/TestHttpConnectionManager.java 4 Jun 2004 01:44:05 -0000 @@ -583,6 +583,31 @@ } + public void testDeleteClosedConnections() { + + MultiThreadedHttpConnectionManager manager = new MultiThreadedHttpConnectionManager(); + + HostConfiguration hostConfig = new HostConfiguration(); + + configureHostConfiguration(hostConfig); + + HttpConnection conn = manager.getConnection(hostConfig); + + assertEquals("connectionsInPool", manager.getConnectionsInPool(), 1); + assertEquals("connectionsInPool(host)", manager.getConnectionsInPool(hostConfig), 1); + + conn.close(); + conn.releaseConnection(); + + assertEquals("connectionsInPool", manager.getConnectionsInPool(), 1); + assertEquals("connectionsInPool(host)", manager.getConnectionsInPool(hostConfig), 1); + + manager.deleteClosedConnections(); + + assertEquals("connectionsInPool", manager.getConnectionsInPool(), 0); + assertEquals("connectionsInPool(host)", manager.getConnectionsInPool(hostConfig), 0); + } + public void testReclaimUnusedConnection() { MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager(); Index: src/test/org/apache/commons/httpclient/TestLocalHostBase.java =================================================================== retrieving revision 1.5 diff -u -r1.5 TestLocalHostBase.java --- src/test/org/apache/commons/httpclient/TestLocalHostBase.java 22 Feb 2004 18:08:49 -0000 1.5 +++ src/test/org/apache/commons/httpclient/TestLocalHostBase.java 4 Jun 2004 01:44:05 -0000 @@ -99,13 +99,22 @@ } else { client = new HttpClient(connectionManager); } - - client.getHostConfiguration().setHost(host, port, protocol); - if (proxyHost != null) { - client.getHostConfiguration().setProxy(proxyHost, proxyPort); - } + + configureHostConfiguration(client.getHostConfiguration()); return client; + } + + /** + * Configures the host config with the correct host and proxy settings. + * + * @param hostConfiguration + */ + public void configureHostConfiguration(HostConfiguration hostConfiguration) { + hostConfiguration.setHost(host, port, protocol); + if (proxyHost != null) { + hostConfiguration.setProxy(proxyHost, proxyPort); + } } /**