HTTPCLIENT-1495: shut down standard connection managers only once

git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1587883 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Oleg Kalnichevski 2014-04-16 11:52:16 +00:00
parent cd1f9fc9f7
commit 64fade92df
2 changed files with 26 additions and 22 deletions

View File

@ -32,6 +32,7 @@ import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.Date; import java.util.Date;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -108,8 +109,7 @@ public class BasicHttpClientConnectionManager implements HttpClientConnectionMan
@GuardedBy("this") @GuardedBy("this")
private ConnectionConfig connConfig; private ConnectionConfig connConfig;
@GuardedBy("this") private final AtomicBoolean isShutdown;
private volatile boolean shutdown;
private static Registry<ConnectionSocketFactory> getDefaultRegistry() { private static Registry<ConnectionSocketFactory> getDefaultRegistry() {
return RegistryBuilder.<ConnectionSocketFactory>create() return RegistryBuilder.<ConnectionSocketFactory>create()
@ -141,6 +141,7 @@ public class BasicHttpClientConnectionManager implements HttpClientConnectionMan
this.expiry = Long.MAX_VALUE; this.expiry = Long.MAX_VALUE;
this.socketConfig = SocketConfig.DEFAULT; this.socketConfig = SocketConfig.DEFAULT;
this.connConfig = ConnectionConfig.DEFAULT; this.connConfig = ConnectionConfig.DEFAULT;
this.isShutdown = new AtomicBoolean(false);
} }
public BasicHttpClientConnectionManager( public BasicHttpClientConnectionManager(
@ -256,7 +257,7 @@ public class BasicHttpClientConnectionManager implements HttpClientConnectionMan
} }
synchronized HttpClientConnection getConnection(final HttpRoute route, final Object state) { synchronized HttpClientConnection getConnection(final HttpRoute route, final Object state) {
Asserts.check(!this.shutdown, "Connection manager has been shut down"); Asserts.check(!this.isShutdown.get(), "Connection manager has been shut down");
if (this.log.isDebugEnabled()) { if (this.log.isDebugEnabled()) {
this.log.debug("Get connection for route " + route); this.log.debug("Get connection for route " + route);
} }
@ -284,8 +285,7 @@ public class BasicHttpClientConnectionManager implements HttpClientConnectionMan
if (this.log.isDebugEnabled()) { if (this.log.isDebugEnabled()) {
this.log.debug("Releasing connection " + conn); this.log.debug("Releasing connection " + conn);
} }
if (this.shutdown) { if (this.isShutdown.get()) {
shutdownConnection();
return; return;
} }
try { try {
@ -357,7 +357,7 @@ public class BasicHttpClientConnectionManager implements HttpClientConnectionMan
@Override @Override
public synchronized void closeExpiredConnections() { public synchronized void closeExpiredConnections() {
if (this.shutdown) { if (this.isShutdown.get()) {
return; return;
} }
if (!this.leased) { if (!this.leased) {
@ -368,7 +368,7 @@ public class BasicHttpClientConnectionManager implements HttpClientConnectionMan
@Override @Override
public synchronized void closeIdleConnections(final long idletime, final TimeUnit tunit) { public synchronized void closeIdleConnections(final long idletime, final TimeUnit tunit) {
Args.notNull(tunit, "Time unit"); Args.notNull(tunit, "Time unit");
if (this.shutdown) { if (this.isShutdown.get()) {
return; return;
} }
if (!this.leased) { if (!this.leased) {
@ -385,11 +385,9 @@ public class BasicHttpClientConnectionManager implements HttpClientConnectionMan
@Override @Override
public synchronized void shutdown() { public synchronized void shutdown() {
if (this.shutdown) { if (this.isShutdown.compareAndSet(false, true)) {
return; shutdownConnection();
} }
this.shutdown = true;
shutdownConnection();
} }
} }

View File

@ -35,6 +35,7 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -92,6 +93,7 @@ public class PoolingHttpClientConnectionManager
private final ConfigData configData; private final ConfigData configData;
private final CPool pool; private final CPool pool;
private final HttpClientConnectionOperator connectionOperator; private final HttpClientConnectionOperator connectionOperator;
private final AtomicBoolean isShutDown;
private static Registry<ConnectionSocketFactory> getDefaultRegistry() { private static Registry<ConnectionSocketFactory> getDefaultRegistry() {
return RegistryBuilder.<ConnectionSocketFactory>create() return RegistryBuilder.<ConnectionSocketFactory>create()
@ -157,11 +159,12 @@ public class PoolingHttpClientConnectionManager
final HttpClientConnectionOperator httpClientConnectionOperator, final HttpClientConnectionOperator httpClientConnectionOperator,
final HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> connFactory, final HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> connFactory,
final long timeToLive, final TimeUnit tunit) { final long timeToLive, final TimeUnit tunit) {
super(); super();
this.configData = new ConfigData(); this.configData = new ConfigData();
this.pool = new CPool( this.pool = new CPool(new InternalConnectionFactory(
new InternalConnectionFactory(this.configData, connFactory), 2, 20, timeToLive, tunit); this.configData, connFactory), 2, 20, timeToLive, tunit);
this.connectionOperator = Args.notNull(httpClientConnectionOperator, "HttpClientConnectionOperator"); this.connectionOperator = Args.notNull(httpClientConnectionOperator, "HttpClientConnectionOperator");
this.isShutDown = new AtomicBoolean(false);
} }
/** /**
@ -177,6 +180,7 @@ public class PoolingHttpClientConnectionManager
this.pool = pool; this.pool = pool;
this.connectionOperator = new DefaultHttpClientConnectionOperator( this.connectionOperator = new DefaultHttpClientConnectionOperator(
socketFactoryRegistry, schemePortResolver, dnsResolver); socketFactoryRegistry, schemePortResolver, dnsResolver);
this.isShutDown = new AtomicBoolean(false);
} }
@Override @Override
@ -368,13 +372,15 @@ public class PoolingHttpClientConnectionManager
@Override @Override
public void shutdown() { public void shutdown() {
this.log.debug("Connection manager is shutting down"); if (this.isShutDown.compareAndSet(false, true)) {
try { this.log.debug("Connection manager is shutting down");
this.pool.shutdown(); try {
} catch (final IOException ex) { this.pool.shutdown();
this.log.debug("I/O exception shutting down connection manager", ex); } catch (final IOException ex) {
this.log.debug("I/O exception shutting down connection manager", ex);
}
this.log.debug("Connection manager shut down");
} }
this.log.debug("Connection manager shut down");
} }
@Override @Override