hc-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Tim Boemker (JIRA)" <j...@apache.org>
Subject [jira] Updated: (HTTPCLIENT-881) AbstractClientConnAdapter doesn't ensure that only one of ConnectionReleaseTrigger.abortConnection, .releaseConnection has effect
Date Thu, 15 Oct 2009 21:39:31 GMT

     [ https://issues.apache.org/jira/browse/HTTPCLIENT-881?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]

Tim Boemker updated HTTPCLIENT-881:
-----------------------------------

    Attachment: HTTPCLIENT-881.patch

Also attached.

Index: AbstractClientConnAdapter.java
===================================================================
--- AbstractClientConnAdapter.java      (revision 825665)
+++ AbstractClientConnAdapter.java      (working copy)
@@ -86,6 +86,9 @@
     /** True if the connection has been aborted. */
     private volatile boolean aborted;

+    /** True if the connection has been released. */
+    private boolean released;
+
     /** The duration this is valid for while idle (in ms). */
     private volatile long duration;

@@ -316,16 +319,25 @@
     }

     public void releaseConnection() {
+        synchronized(this) {
+            if (aborted || released) {
+                return;
+            }
+            released = true;
+        }
         if (connManager != null) {
             connManager.releaseConnection(this, duration, TimeUnit.MILLISECONDS);
         }
     }

+
     public void abortConnection() {
-        if (aborted) {
-            return;
+        synchronized(this) {
+            if (aborted || released) {
+                return;
+            }
+            aborted = true;
         }
-        aborted = true;
         unmarkReusable();
         try {
             shutdown();





> AbstractClientConnAdapter doesn't ensure that only one of ConnectionReleaseTrigger.abortConnection,
.releaseConnection has effect
> ---------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: HTTPCLIENT-881
>                 URL: https://issues.apache.org/jira/browse/HTTPCLIENT-881
>             Project: HttpComponents HttpClient
>          Issue Type: Bug
>          Components: HttpConn
>    Affects Versions: 4.0 Final
>            Reporter: Tim Boemker
>             Fix For: 4.1 Alpha1
>
>         Attachments: HTTPCLIENT-881.patch
>
>
> If HttpUriRequest.abort() is called at about the same time that the request completes,
it's possible for an aborted connection to be returned to the pool.  The next time the connection
is used, HttpClient.execute fails without retrying, throwing this exception:
> java.io.IOException: Connection already shutdown
> 	at org.apache.http.impl.conn.DefaultClientConnection.opening(DefaultClientConnection.java:112)
> 	at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:120)
> 	at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:147)
> 	at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:101)
> 	at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:381)
> 	at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:641)
> 	at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:576)
> Steps to reproduce:
> 1) Set a breakpoint in ThreadSafeClientConnManager.releaseConnection just after "reusable"
is set (and found to be true).
> 2) Run to the breakpoint in releaseConnection.
> 3) Call HttpUriRequest.abort.
> 4) Let releaseConnection complete.
> When the connection is next used, the exception will be thrown.
> Snippet from ThreadSafeClientConnManager:
>     public void releaseConnection(ManagedClientConnection conn, long validDuration, TimeUnit
timeUnit) {
> 		...
>             boolean reusable = hca.isMarkedReusable();
>             if (log.isDebugEnabled()) {                             // breakpoint here
>                 if (reusable) {
>                     log.debug("Released connection is reusable.");
>                 } else {
>                     log.debug("Released connection is not reusable.");
>                 }
>             }
>             hca.detach();
>             if (entry != null) {
>                 connectionPool.freeEntry(entry, reusable, validDuration, timeUnit);
>             }
>         }
>     }
> I think that AbstractClientConnAdapter should be modified as follows:
> 1) Add "released" flag:
>     /** True if the connection has been released. */
>     private boolean released;
> 2) Modify abortConnection:
>     public void abortConnection() {
>         synchronized(this) {
>             if (aborted || released) {
>                 return;
>             }
>             aborted = true;
>         }
>         unmarkReusable(); // this line and all that follow unchanged
> 3) Modify releaseConnection:
>     public void releaseConnection() {
>         synchronized(this) {
>             if (aborted || released) {
>                 return;
>             }
>             released = true;
>         }
>         if (connManager != null) {
>             connManager.releaseConnection(this, duration, TimeUnit.MILLISECONDS);
>         }
>     }

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org


Mime
View raw message