You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2011/08/11 09:42:03 UTC

svn commit: r1156520 - in /httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http: impl/nio/client/ impl/nio/conn/ nio/conn/

Author: olegk
Date: Thu Aug 11 07:42:02 2011
New Revision: 1156520

URL: http://svn.apache.org/viewvc?rev=1156520&view=rev
Log:
Redesign of the managed connection implementation

Modified:
    httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/impl/nio/client/DefaultAsyncRequestDirector.java
    httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/impl/nio/conn/ClientConnAdaptor.java
    httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/impl/nio/conn/HttpNIOConnPool.java
    httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/impl/nio/conn/PoolingClientConnectionManager.java
    httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/nio/conn/ManagedClientConnection.java
    httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/nio/conn/OperatedClientConnection.java

Modified: httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/impl/nio/client/DefaultAsyncRequestDirector.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/impl/nio/client/DefaultAsyncRequestDirector.java?rev=1156520&r1=1156519&r2=1156520&view=diff
==============================================================================
--- httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/impl/nio/client/DefaultAsyncRequestDirector.java (original)
+++ httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/impl/nio/client/DefaultAsyncRequestDirector.java Thu Aug 11 07:42:02 2011
@@ -377,7 +377,7 @@ class DefaultAsyncRequestDirector<T> imp
                 }
                 this.managedConn.setIdleDuration(duration, TimeUnit.MILLISECONDS);
             } else {
-                this.managedConn.markNonReusable();
+                this.managedConn.unmarkReusable();
                 releaseConnection();
                 invalidateAuthIfSuccessful(this.proxyAuthState);
                 invalidateAuthIfSuccessful(this.targetAuthState);

Modified: httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/impl/nio/conn/ClientConnAdaptor.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/impl/nio/conn/ClientConnAdaptor.java?rev=1156520&r1=1156519&r2=1156520&view=diff
==============================================================================
--- httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/impl/nio/conn/ClientConnAdaptor.java (original)
+++ httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/impl/nio/conn/ClientConnAdaptor.java Thu Aug 11 07:42:02 2011
@@ -35,7 +35,6 @@ import javax.net.ssl.SSLSession;
 import org.apache.http.HttpConnectionMetrics;
 import org.apache.http.HttpException;
 import org.apache.http.HttpHost;
-import org.apache.http.HttpInetConnection;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpResponseFactory;
@@ -45,7 +44,6 @@ import org.apache.http.impl.DefaultHttpR
 import org.apache.http.impl.conn.ConnectionShutdownException;
 import org.apache.http.impl.nio.reactor.SSLIOSession;
 import org.apache.http.impl.nio.reactor.SSLMode;
-import org.apache.http.nio.NHttpConnection;
 import org.apache.http.nio.conn.ClientConnectionManager;
 import org.apache.http.nio.conn.ManagedClientConnection;
 import org.apache.http.nio.conn.OperatedClientConnection;
@@ -61,271 +59,228 @@ import org.apache.http.protocol.HttpCont
 class ClientConnAdaptor implements ManagedClientConnection {
 
     private final ClientConnectionManager manager;
-    private HttpPoolEntry entry;
-    private OperatedClientConnection conn;
-    private volatile boolean released;
+    private volatile HttpPoolEntry poolEntry;
     private volatile boolean reusable;
-    private long expiry;
-    private TimeUnit tunit;
+    private volatile long duration;
 
     public ClientConnAdaptor(
             final ClientConnectionManager manager,
-            final HttpPoolEntry entry) {
+            final HttpPoolEntry poolEntry) {
         super();
         this.manager = manager;
-        this.entry = entry;
-        this.released = false;
+        this.poolEntry = poolEntry;
         this.reusable = true;
-        this.expiry = -1;
-        this.tunit = TimeUnit.MILLISECONDS;
-        IOSession session = entry.getConnection();
-        this.conn = (OperatedClientConnection) session.getAttribute(
-                ExecutionContext.HTTP_CONNECTION);
+        this.duration = Long.MAX_VALUE;
     }
 
-    protected ClientConnectionManager getManager() {
-        return this.manager;
+    HttpPoolEntry getPoolEntry() {
+        return this.poolEntry;
     }
 
-    protected HttpPoolEntry getEntry() {
-        return this.entry;
+    HttpPoolEntry detach() {
+        HttpPoolEntry local = this.poolEntry;
+        this.poolEntry = null;
+        return local;
     }
 
-    public synchronized void releaseConnection() {
-        if (this.released) {
-            return;
-        }
-        this.released = true;
-        this.manager.releaseConnection(this, this.expiry, this.tunit);
-        this.entry = null;
-        this.conn = null;
+    public ClientConnectionManager getManager() {
+        return this.manager;
     }
 
-    public synchronized void abortConnection() {
-        if (this.released) {
-            return;
+    private OperatedClientConnection getConnection() {
+        HttpPoolEntry local = this.poolEntry;
+        if (local == null) {
+            return null;
         }
-        this.released = true;
-        this.reusable = false;
-        this.manager.releaseConnection(this, this.expiry, this.tunit);
-        this.entry = null;
-        this.conn = null;
+        IOSession session = local.getConnection();
+        return (OperatedClientConnection) session.getAttribute(
+                ExecutionContext.HTTP_CONNECTION);
     }
 
-    public synchronized Object getState() {
-        if (this.released) {
-            return null;
+    private OperatedClientConnection ensureConnection() {
+        HttpPoolEntry local = this.poolEntry;
+        if (local == null) {
+            throw new ConnectionShutdownException();
         }
-        return this.entry.getState();
+        IOSession session = local.getConnection();
+        return (OperatedClientConnection) session.getAttribute(
+                ExecutionContext.HTTP_CONNECTION);
     }
 
-    public synchronized void setState(final Object state) {
-        if (this.released) {
-            return;
+    private HttpPoolEntry ensurePoolEntry() {
+        HttpPoolEntry local = this.poolEntry;
+        if (local == null) {
+            throw new ConnectionShutdownException();
         }
-        this.entry.setState(state);
+        return local;
     }
 
-    public boolean isReusable() {
-        return this.reusable && this.conn != null && this.conn.isOpen();
+    public void close() throws IOException {
+        OperatedClientConnection conn = getConnection();
+        if (conn != null) {
+            conn.close();
+        }
     }
 
-    public synchronized void markNonReusable() {
-        if (this.released) {
-            return;
+    public void shutdown() throws IOException {
+        OperatedClientConnection conn = getConnection();
+        if (conn != null) {
+            conn.shutdown();
         }
-        this.reusable = false;
     }
 
-    public synchronized void markReusable() {
-        if (this.released) {
-            return;
+    public boolean isOpen() {
+        OperatedClientConnection conn = getConnection();
+        if (conn != null) {
+            return conn.isOpen();
+        } else {
+            return false;
         }
-        this.reusable = true;
     }
 
-    public synchronized void shutdown() throws IOException {
-        if (this.released) {
-            return;
-        }
-        this.conn.shutdown();
-        this.reusable = false;
+    public boolean isStale() {
+        return isOpen();
     }
 
-    public synchronized void close() throws IOException {
-        if (this.released) {
-            return;
-        }
-        this.conn.close();
-        this.reusable = false;
-        releaseConnection();
+    public void setSocketTimeout(int timeout) {
+        OperatedClientConnection conn = ensureConnection();
+        conn.setSocketTimeout(timeout);
     }
 
-    private void assertValid() {
-        if (this.released) {
-            throw new ConnectionShutdownException();
-        }
+    public int getSocketTimeout() {
+        OperatedClientConnection conn = ensureConnection();
+        return conn.getSocketTimeout();
     }
 
-    private OperatedClientConnection getWrappedConnection() {
-        OperatedClientConnection conn = this.conn;
-        if (conn == null) {
-            throw new ConnectionShutdownException();
-        }
-        return conn;
+    public HttpConnectionMetrics getMetrics() {
+        OperatedClientConnection conn = ensureConnection();
+        return conn.getMetrics();
     }
 
-    public synchronized boolean isOpen() {
-        return !this.released && this.conn != null && this.conn.isOpen();
+    public InetAddress getLocalAddress() {
+        OperatedClientConnection conn = ensureConnection();
+        return conn.getLocalAddress();
     }
 
-    public boolean isStale() {
-        return isOpen();
+    public int getLocalPort() {
+        OperatedClientConnection conn = ensureConnection();
+        return conn.getLocalPort();
     }
 
-    public HttpRoute getRoute() {
-        assertValid();
-        return this.entry.getEffectiveRoute();
+    public InetAddress getRemoteAddress() {
+        OperatedClientConnection conn = ensureConnection();
+        return conn.getRemoteAddress();
     }
 
-    public SSLSession getSSLSession() {
-        return null;
+    public int getRemotePort() {
+        OperatedClientConnection conn = ensureConnection();
+        return conn.getRemotePort();
     }
 
-    public boolean isSecure() {
-        assertValid();
-        OperatedClientConnection conn = getWrappedConnection();
-        return conn.getSSLIOSession() != null;
+    public int getStatus() {
+        OperatedClientConnection conn = ensureConnection();
+        return conn.getStatus();
     }
 
-    public InetAddress getLocalAddress() {
-        assertValid();
-        OperatedClientConnection conn = getWrappedConnection();
-        if (conn instanceof HttpInetConnection) {
-            return ((HttpInetConnection) conn).getLocalAddress();
-        } else {
-            return null;
-        }
+    public HttpRequest getHttpRequest() {
+        OperatedClientConnection conn = ensureConnection();
+        return conn.getHttpRequest();
     }
 
-    public int getLocalPort() {
-        assertValid();
-        OperatedClientConnection conn = getWrappedConnection();
-        if (conn instanceof HttpInetConnection) {
-            return ((HttpInetConnection) conn).getLocalPort();
-        } else {
-            return -1;
-        }
+    public HttpResponse getHttpResponse() {
+        OperatedClientConnection conn = ensureConnection();
+        return conn.getHttpResponse();
     }
 
-    public InetAddress getRemoteAddress() {
-        assertValid();
-        OperatedClientConnection conn = getWrappedConnection();
-        if (conn instanceof HttpInetConnection) {
-            return ((HttpInetConnection) conn).getRemoteAddress();
-        } else {
-            return null;
-        }
+    public HttpContext getContext() {
+        OperatedClientConnection conn = ensureConnection();
+        return conn.getContext();
     }
 
-    public int getRemotePort() {
-        assertValid();
-        OperatedClientConnection conn = getWrappedConnection();
-        if (conn instanceof HttpInetConnection) {
-            return ((HttpInetConnection) conn).getRemotePort();
-        } else {
-            return -1;
-        }
+    public void requestInput() {
+        OperatedClientConnection conn = ensureConnection();
+        conn.requestInput();
     }
 
-    public synchronized HttpConnectionMetrics getMetrics() {
-        assertValid();
-        OperatedClientConnection conn = getWrappedConnection();
-        return conn.getMetrics();
+    public void suspendInput() {
+        OperatedClientConnection conn = ensureConnection();
+        conn.suspendInput();
     }
 
-    public synchronized int getSocketTimeout() {
-        assertValid();
-        OperatedClientConnection conn = getWrappedConnection();
-        return conn.getSocketTimeout();
+    public void requestOutput() {
+        OperatedClientConnection conn = ensureConnection();
+        conn.requestOutput();
     }
 
-    public synchronized void setSocketTimeout(int timeout) {
-        assertValid();
-        OperatedClientConnection conn = getWrappedConnection();
-        conn.setSocketTimeout(timeout);
+    public void suspendOutput() {
+        OperatedClientConnection conn = ensureConnection();
+        conn.suspendOutput();
     }
 
-    public synchronized int getStatus() {
-        return this.conn == null || !this.conn.isOpen() ?
-                NHttpConnection.CLOSED : NHttpConnection.ACTIVE;
+    public void submitRequest(final HttpRequest request) throws IOException, HttpException {
+        OperatedClientConnection conn = ensureConnection();
+        conn.submitRequest(request);
     }
 
-    public synchronized HttpContext getContext() {
-        assertValid();
-        OperatedClientConnection conn = getWrappedConnection();
-        return conn.getContext();
+    public boolean isRequestSubmitted() {
+        OperatedClientConnection conn = ensureConnection();
+        return conn.isRequestSubmitted();
     }
 
-    public synchronized HttpRequest getHttpRequest() {
-        assertValid();
-        OperatedClientConnection conn = getWrappedConnection();
-        return conn.getHttpRequest();
+    public void resetOutput() {
+        OperatedClientConnection conn = ensureConnection();
+        conn.resetOutput();
     }
 
-    public synchronized HttpResponse getHttpResponse() {
-        assertValid();
-        OperatedClientConnection conn = getWrappedConnection();
-        return conn.getHttpResponse();
+    public void resetInput() {
+        OperatedClientConnection conn = ensureConnection();
+        conn.resetInput();
     }
 
-    public synchronized void requestInput() {
-        assertValid();
-        OperatedClientConnection conn = getWrappedConnection();
-        conn.requestInput();
+    public boolean isSecure() {
+        OperatedClientConnection conn = ensureConnection();
+        return conn.getSSLIOSession() != null;
     }
 
-    public synchronized void requestOutput() {
-        assertValid();
-        OperatedClientConnection conn = getWrappedConnection();
-        conn.requestOutput();
+    public HttpRoute getRoute() {
+        HttpPoolEntry entry = ensurePoolEntry();
+        return entry.getEffectiveRoute();
     }
 
-    public synchronized void suspendInput() {
-        assertValid();
-        OperatedClientConnection conn = getWrappedConnection();
-        conn.suspendInput();
+    public SSLSession getSSLSession() {
+        OperatedClientConnection conn = ensureConnection();
+        SSLIOSession iosession = conn.getSSLIOSession();
+        return iosession != null ? iosession.getSSLSession() : null;
     }
 
-    public synchronized void suspendOutput() {
-        assertValid();
-        OperatedClientConnection conn = getWrappedConnection();
-        conn.suspendOutput();
+    public Object getState() {
+        HttpPoolEntry entry = ensurePoolEntry();
+        return entry.getState();
     }
 
-    public synchronized boolean isRequestSubmitted() {
-        assertValid();
-        OperatedClientConnection conn = getWrappedConnection();
-        return conn.isRequestSubmitted();
+    public void setState(final Object state) {
+        HttpPoolEntry entry = ensurePoolEntry();
+        entry.setState(state);
     }
 
-    public synchronized void resetInput() {
-        assertValid();
-        OperatedClientConnection conn = getWrappedConnection();
-        conn.resetInput();
+    public void markReusable() {
+        this.reusable = true;
     }
 
-    public synchronized void resetOutput() {
-        assertValid();
-        OperatedClientConnection conn = getWrappedConnection();
-        conn.resetOutput();
+    public void unmarkReusable() {
+        this.reusable = false;
     }
 
-    public synchronized void submitRequest(
-            final HttpRequest request) throws IOException, HttpException {
-        assertValid();
-        OperatedClientConnection conn = getWrappedConnection();
-        conn.submitRequest(request);
+    public boolean isMarkedReusable() {
+        return this.reusable;
+    }
+
+    public void setIdleDuration(long duration, TimeUnit unit) {
+        if(duration > 0) {
+            this.duration = unit.toMillis(duration);
+        } else {
+            this.duration = -1;
+        }
     }
 
     protected ByteBufferAllocator createByteBufferAllocator() {
@@ -339,15 +294,15 @@ class ClientConnAdaptor implements Manag
     public synchronized void open(
             final HttpRoute route,
             final HttpContext context, final HttpParams params) throws IOException {
-        assertValid();
-        RouteTracker tracker = this.entry.getTracker();
+        HttpPoolEntry entry = ensurePoolEntry();
+        RouteTracker tracker = entry.getTracker();
         if (tracker.isConnected()) {
             throw new IllegalStateException("Connection already open");
         }
 
         HttpHost target = route.getTargetHost();
         HttpHost proxy = route.getProxyHost();
-        IOSession iosession = this.entry.getConnection();
+        IOSession iosession = entry.getConnection();
 
         if (proxy == null) {
             Scheme scheme = this.manager.getSchemeRegistry().getScheme(target);
@@ -360,14 +315,13 @@ class ClientConnAdaptor implements Manag
         }
 
         OperatedClientConnection conn = new DefaultClientConnection(
-                "http-outgoing-" + this.entry.getId(),
+                "http-outgoing-" + entry.getId(),
                 iosession,
                 createHttpResponseFactory(),
                 createByteBufferAllocator(),
                 params);
         iosession.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
 
-        this.conn = conn;
         if (proxy == null) {
             tracker.connectTarget(conn.getSSLIOSession() != null);
         } else {
@@ -377,8 +331,8 @@ class ClientConnAdaptor implements Manag
 
     public synchronized void tunnelProxy(
             final HttpHost next, final HttpParams params) throws IOException {
-        assertValid();
-        RouteTracker tracker = this.entry.getTracker();
+        HttpPoolEntry entry = ensurePoolEntry();
+        RouteTracker tracker = entry.getTracker();
         if (!tracker.isConnected()) {
             throw new IllegalStateException("Connection not open");
         }
@@ -387,8 +341,8 @@ class ClientConnAdaptor implements Manag
 
     public synchronized void tunnelTarget(
             final HttpParams params) throws IOException {
-        assertValid();
-        RouteTracker tracker = this.entry.getTracker();
+        HttpPoolEntry entry = ensurePoolEntry();
+        RouteTracker tracker = entry.getTracker();
         if (!tracker.isConnected()) {
             throw new IllegalStateException("Connection not open");
         }
@@ -400,9 +354,8 @@ class ClientConnAdaptor implements Manag
 
     public synchronized void layerProtocol(
             final HttpContext context, final HttpParams params) throws IOException {
-        assertValid();
-        OperatedClientConnection conn = getWrappedConnection();
-        RouteTracker tracker = this.entry.getTracker();
+        HttpPoolEntry entry = ensurePoolEntry();
+        RouteTracker tracker = entry.getTracker();
         if (!tracker.isConnected()) {
             throw new IllegalStateException("Connection not open");
         }
@@ -419,40 +372,38 @@ class ClientConnAdaptor implements Manag
             throw new IllegalStateException(scheme.getName() +
                     " scheme does not provider support for protocol layering");
         }
-        IOSession iosession = this.entry.getConnection();
+        IOSession iosession = entry.getConnection();
         SSLIOSession ssliosession = (SSLIOSession) layeringStrategy.layer(iosession);
         ssliosession.bind(SSLMode.CLIENT, params);
 
+        OperatedClientConnection conn = (OperatedClientConnection) iosession.getAttribute(
+                ExecutionContext.HTTP_CONNECTION);
         conn.upgrade(ssliosession);
         tracker.layerProtocol(layeringStrategy.isSecure());
     }
 
-    public synchronized void setIdleDuration(final long duration, final TimeUnit tunit) {
-        if (tunit == null) {
-            throw new IllegalArgumentException("Time unit may not be null");
-        }
-        this.expiry = duration;
-        this.tunit = tunit;
-    }
-
-    @Override
-    public synchronized String toString() {
-        HttpRoute route = this.entry.getPlannedRoute();
-        StringBuilder buffer = new StringBuilder();
-        buffer.append("HTTP connection: ");
-        if (route.getLocalAddress() != null) {
-            buffer.append(route.getLocalAddress());
-            buffer.append("->");
-        }
-        for (int i = 0; i < route.getHopCount(); i++) {
-            buffer.append(route.getHopTarget(i));
-            buffer.append("->");
-        }
-        buffer.append(route.getTargetHost());
-        if (this.released) {
-            buffer.append(" (released)");
+    public synchronized void releaseConnection() {
+        if (this.poolEntry == null) {
+            return;
+        }
+        this.manager.releaseConnection(this, this.duration, TimeUnit.MILLISECONDS);
+        this.poolEntry = null;
+    }
+
+    public synchronized void abortConnection() {
+        if (this.poolEntry == null) {
+            return;
+        }
+        this.reusable = false;
+        IOSession iosession = this.poolEntry.getConnection();
+        OperatedClientConnection conn = (OperatedClientConnection) iosession.getAttribute(
+                ExecutionContext.HTTP_CONNECTION);
+        try {
+            conn.shutdown();
+        } catch (IOException ignore) {
         }
-        return buffer.toString();
+        this.manager.releaseConnection(this, this.duration, TimeUnit.MILLISECONDS);
+        this.poolEntry = null;
     }
 
 }

Modified: httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/impl/nio/conn/HttpNIOConnPool.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/impl/nio/conn/HttpNIOConnPool.java?rev=1156520&r1=1156519&r2=1156520&view=diff
==============================================================================
--- httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/impl/nio/conn/HttpNIOConnPool.java (original)
+++ httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/impl/nio/conn/HttpNIOConnPool.java Thu Aug 11 07:42:02 2011
@@ -57,7 +57,7 @@ class HttpNIOConnPool extends AbstractNI
             final ConnectingIOReactor ioreactor,
             final SchemeRegistry schemeRegistry,
             long connTimeToLive, final TimeUnit tunit) {
-        super(ioreactor, 20, 50);
+        super(ioreactor, 2, 20);
         this.log = log;
         this.schemeRegistry = schemeRegistry;
         this.connTimeToLive = connTimeToLive;

Modified: httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/impl/nio/conn/PoolingClientConnectionManager.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/impl/nio/conn/PoolingClientConnectionManager.java?rev=1156520&r1=1156519&r2=1156520&view=diff
==============================================================================
--- httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/impl/nio/conn/PoolingClientConnectionManager.java (original)
+++ httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/impl/nio/conn/PoolingClientConnectionManager.java Thu Aug 11 07:42:02 2011
@@ -183,31 +183,46 @@ public class PoolingClientConnectionMana
         if (tunit == null) {
             throw new IllegalArgumentException("Time unit may not be null");
         }
-        ClientConnAdaptor adaptor = (ClientConnAdaptor) conn;
-        ClientConnectionManager manager = adaptor.getManager();
+        ClientConnAdaptor managedConn = (ClientConnAdaptor) conn;
+        ClientConnectionManager manager = managedConn.getManager();
         if (manager != null && manager != this) {
             throw new IllegalArgumentException("Connection not obtained from this manager");
         }
         if (this.pool.isShutdown()) {
             return;
         }
-        HttpPoolEntry entry = adaptor.getEntry();
-        boolean reusable = adaptor.isReusable();
-        if (reusable) {
-            entry.updateExpiry(keepalive, tunit);
-            if (this.log.isDebugEnabled()) {
-                String s;
-                if (keepalive > 0) {
-                    s = "for " + keepalive + " " + tunit;
-                } else {
-                    s = "indefinitely";
+
+        synchronized (managedConn) {
+            HttpPoolEntry entry = managedConn.detach();
+            if (entry == null) {
+                return;
+            }
+            try {
+                if (managedConn.isOpen() && !managedConn.isMarkedReusable()) {
+                    try {
+                        managedConn.shutdown();
+                    } catch (IOException iox) {
+                        if (this.log.isDebugEnabled()) {
+                            this.log.debug("I/O exception shutting down released connection", iox);
+                        }
+                    }
+                }
+                entry.updateExpiry(keepalive, tunit != null ? tunit : TimeUnit.MILLISECONDS);
+                if (this.log.isDebugEnabled()) {
+                    String s;
+                    if (keepalive > 0) {
+                        s = "for " + keepalive + " " + tunit;
+                    } else {
+                        s = "indefinitely";
+                    }
+                    this.log.debug("Connection " + format(entry) + " can be kept alive " + s);
                 }
-                this.log.debug("Connection " + format(entry) + " can be kept alive " + s);
+            } finally {
+                this.pool.release(entry, managedConn.isMarkedReusable());
+            }
+            if (this.log.isDebugEnabled()) {
+                this.log.debug("Connection released: " + format(entry) + formatStats(entry.getRoute()));
             }
-        }
-        this.pool.release(entry, reusable);
-        if (this.log.isDebugEnabled()) {
-            this.log.debug("Connection released: " + format(entry) + formatStats(entry.getRoute()));
         }
     }
 

Modified: httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/nio/conn/ManagedClientConnection.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/nio/conn/ManagedClientConnection.java?rev=1156520&r1=1156519&r2=1156520&view=diff
==============================================================================
--- httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/nio/conn/ManagedClientConnection.java (original)
+++ httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/nio/conn/ManagedClientConnection.java Thu Aug 11 07:42:02 2011
@@ -46,9 +46,9 @@ public interface ManagedClientConnection
 
     void markReusable();
 
-    void markNonReusable();
+    void unmarkReusable();
 
-    boolean isReusable();
+    boolean isMarkedReusable();
 
     void open(HttpRoute route, HttpContext context, HttpParams params) throws IOException;
 

Modified: httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/nio/conn/OperatedClientConnection.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/nio/conn/OperatedClientConnection.java?rev=1156520&r1=1156519&r2=1156520&view=diff
==============================================================================
--- httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/nio/conn/OperatedClientConnection.java (original)
+++ httpcomponents/httpasyncclient/branches/conn-mgmt-redesign/httpasyncclient/src/main/java/org/apache/http/nio/conn/OperatedClientConnection.java Thu Aug 11 07:42:02 2011
@@ -26,12 +26,14 @@
  */
 package org.apache.http.nio.conn;
 
+import org.apache.http.HttpInetConnection;
 import org.apache.http.impl.nio.reactor.SSLIOSession;
 import org.apache.http.nio.NHttpClientConnection;
 import org.apache.http.nio.NHttpClientIOTarget;
 import org.apache.http.nio.reactor.IOSession;
 
-public interface OperatedClientConnection extends NHttpClientConnection, NHttpClientIOTarget {
+public interface OperatedClientConnection
+    extends NHttpClientConnection, HttpInetConnection, NHttpClientIOTarget {
 
     void upgrade(IOSession iosession);