diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt index 31e1b510d..704316abd 100644 --- a/RELEASE_NOTES.txt +++ b/RELEASE_NOTES.txt @@ -1,6 +1,11 @@ Changes since 4.0 ------------------- +* [HTTPCLIENT-881] Fixed race condition in AbstractClientConnAdapter that makes it + possible for an aborted connection to be returned to the pool. + Contributed by Tim Boemker and + Oleg Kalnichevski + * [HTTPCLIENT-832] Distinguish cookie format errors from violations of restrictions imposed by a cookie specification. In the latter case CookieRestrictionViolationException will be thrown. 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 d76d5ac5c..af7796e5d 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 @@ -83,8 +83,8 @@ public abstract class AbstractClientConnAdapter implements ManagedClientConnecti /** The reusability marker. */ private volatile boolean markedReusable; - /** True if the connection has been aborted. */ - private volatile boolean aborted; + /** True if the connection has been shut down or released. */ + private volatile boolean shutdown; /** The duration this is valid for while idle (in ms). */ private volatile long duration; @@ -104,7 +104,7 @@ public abstract class AbstractClientConnAdapter implements ManagedClientConnecti connManager = mgr; wrappedConnection = conn; markedReusable = false; - aborted = false; + shutdown = false; duration = Long.MAX_VALUE; } // @@ -133,7 +133,7 @@ public abstract class AbstractClientConnAdapter implements ManagedClientConnecti * @throws InterruptedIOException if the connection has been aborted */ protected final void assertNotAborted() throws InterruptedIOException { - if (aborted) { + if (shutdown) { throw new InterruptedIOException("Connection has been shut down."); } } @@ -160,7 +160,7 @@ public abstract class AbstractClientConnAdapter implements ManagedClientConnecti } public boolean isStale() { - if (aborted) + if (shutdown) return true; OperatedClientConnection conn = getWrappedConnection(); if (conn == null) @@ -316,16 +316,17 @@ public abstract class AbstractClientConnAdapter implements ManagedClientConnecti } public void releaseConnection() { + shutdown = true; if (connManager != null) { connManager.releaseConnection(this, duration, TimeUnit.MILLISECONDS); } } public void abortConnection() { - if (aborted) { + if (shutdown) { return; } - aborted = true; + shutdown = true; unmarkReusable(); try { shutdown(); @@ -345,7 +346,9 @@ public abstract class AbstractClientConnAdapter implements ManagedClientConnecti // manager if #abortConnection() is called from the main execution // thread while there is no blocking I/O operation. if (executionThread.equals(Thread.currentThread())) { - releaseConnection(); + if (connManager != null) { + connManager.releaseConnection(this, duration, TimeUnit.MILLISECONDS); + } } }