diff --git a/httpclient/src/main/java/org/apache/http/impl/conn/AbstractClientConnAdapter.java b/httpclient/src/main/java/org/apache/http/impl/conn/AbstractClientConnAdapter.java index 771fdcc1a..55a73dd24 100644 --- a/httpclient/src/main/java/org/apache/http/impl/conn/AbstractClientConnAdapter.java +++ b/httpclient/src/main/java/org/apache/http/impl/conn/AbstractClientConnAdapter.java @@ -108,7 +108,7 @@ public abstract class AbstractClientConnAdapter implements ManagedClientConnecti * Detaches this adapter from the wrapped connection. * This adapter becomes useless. */ - protected void detach() { + protected synchronized void detach() { wrappedConnection = null; connManager = null; // base class attribute duration = Long.MAX_VALUE; @@ -310,7 +310,7 @@ public abstract class AbstractClientConnAdapter implements ManagedClientConnecti } } - public void releaseConnection() { + public synchronized void releaseConnection() { if (shutdown) { return; } @@ -320,7 +320,7 @@ public abstract class AbstractClientConnAdapter implements ManagedClientConnecti } } - public void abortConnection() { + public synchronized void abortConnection() { if (shutdown) { return; } diff --git a/httpclient/src/main/java/org/apache/http/impl/conn/AbstractPooledConnAdapter.java b/httpclient/src/main/java/org/apache/http/impl/conn/AbstractPooledConnAdapter.java index 22536e6ea..2dbf9807e 100644 --- a/httpclient/src/main/java/org/apache/http/impl/conn/AbstractPooledConnAdapter.java +++ b/httpclient/src/main/java/org/apache/http/impl/conn/AbstractPooledConnAdapter.java @@ -81,9 +81,9 @@ public abstract class AbstractPooledConnAdapter extends AbstractClientConnAdapte * This adapter becomes useless. */ @Override - protected void detach() { - super.detach(); + protected synchronized void detach() { poolEntry = null; + super.detach(); } public HttpRoute getRoute() { diff --git a/httpclient/src/main/java/org/apache/http/impl/conn/tsccm/BasicPooledConnAdapter.java b/httpclient/src/main/java/org/apache/http/impl/conn/tsccm/BasicPooledConnAdapter.java index 46262a519..e304f6a61 100644 --- a/httpclient/src/main/java/org/apache/http/impl/conn/tsccm/BasicPooledConnAdapter.java +++ b/httpclient/src/main/java/org/apache/http/impl/conn/tsccm/BasicPooledConnAdapter.java @@ -26,13 +26,10 @@ 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 @@ -72,7 +69,6 @@ public class BasicPooledConnAdapter extends AbstractPooledConnAdapter { } - // non-javadoc, see base class @Override protected void detach() { // override needed only to make method visible in this package diff --git a/httpclient/src/main/java/org/apache/http/impl/conn/tsccm/ThreadSafeClientConnManager.java b/httpclient/src/main/java/org/apache/http/impl/conn/tsccm/ThreadSafeClientConnManager.java index d1ee6908a..e0dd510d5 100644 --- a/httpclient/src/main/java/org/apache/http/impl/conn/tsccm/ThreadSafeClientConnManager.java +++ b/httpclient/src/main/java/org/apache/http/impl/conn/tsccm/ThreadSafeClientConnManager.java @@ -220,37 +220,38 @@ public class ThreadSafeClientConnManager implements ClientConnectionManager { throw new IllegalArgumentException ("Connection not obtained from this manager."); } - - try { - // make sure that the response has been read completely - if (hca.isOpen() && !hca.isMarkedReusable()) { - // 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 { + synchronized (hca) { BasicPoolEntry entry = (BasicPoolEntry) hca.getPoolEntry(); - boolean reusable = hca.isMarkedReusable(); - if (log.isDebugEnabled()) { - if (reusable) { - log.debug("Released connection is reusable."); - } else { - log.debug("Released connection is not reusable."); - } + if (entry == null) { + return; } - hca.detach(); - if (entry != null) { + try { + // make sure that the response has been read completely + if (hca.isOpen() && !hca.isMarkedReusable()) { + // 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) { + if (log.isDebugEnabled()) + log.debug("Exception shutting down released connection.", + iox); + } finally { + boolean reusable = hca.isMarkedReusable(); + if (log.isDebugEnabled()) { + if (reusable) { + log.debug("Released connection is reusable."); + } else { + log.debug("Released connection is not reusable."); + } + } + hca.detach(); pool.freeEntry(entry, reusable, validDuration, timeUnit); } }