HTTPASYNC-88: persistent connections can time out while kept alive in the pool causing unexpected SocketTimeoutException

git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpasyncclient/branches/4.0.x@1659666 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt
index 3ab75df..8f1a9cb 100644
--- a/RELEASE_NOTES.txt
+++ b/RELEASE_NOTES.txt
@@ -1,6 +1,10 @@
 Changes since 4.0.2
 -------------------
 
+* [HTTPASYNC-88] persistent connections can time out while kept alive in the pool
+  causing unexpected SocketTimeoutException
+  Contributed by Oleg Kalnichevski <olegk at apache.org>
+
 * [HTTPASYNC-86]: fixed a race condition upon connection lease from the connection pool: 
   in very rare  circumstances the main execution thread can get jammed for so long 
   that the I/O dispatch thread succeeds in completing the request and releasing the connection 
diff --git a/httpasyncclient/src/main/java/org/apache/http/impl/nio/conn/CPool.java b/httpasyncclient/src/main/java/org/apache/http/impl/nio/conn/CPool.java
index 71e990a..eaa1e18 100644
--- a/httpasyncclient/src/main/java/org/apache/http/impl/nio/conn/CPool.java
+++ b/httpasyncclient/src/main/java/org/apache/http/impl/nio/conn/CPool.java
@@ -32,6 +32,7 @@
 import org.apache.commons.logging.LogFactory;
 import org.apache.http.annotation.ThreadSafe;
 import org.apache.http.conn.routing.HttpRoute;
+import org.apache.http.nio.NHttpClientConnection;
 import org.apache.http.nio.conn.ManagedNHttpClientConnection;
 import org.apache.http.nio.pool.AbstractNIOConnPool;
 import org.apache.http.nio.pool.NIOConnFactory;
@@ -59,7 +60,22 @@
 
     @Override
     protected CPoolEntry createEntry(final HttpRoute route, final ManagedNHttpClientConnection conn) {
-        return new CPoolEntry(this.log, conn.getId(), route, conn, this.timeToLive, this.tunit);
+        final CPoolEntry entry =  new CPoolEntry(this.log, conn.getId(), route, conn, this.timeToLive, this.tunit);
+        entry.setSocketTimeout(conn.getSocketTimeout());
+        return entry;
+    }
+
+    @Override
+    protected void onLease(final CPoolEntry entry) {
+        final NHttpClientConnection conn = entry.getConnection();
+        conn.setSocketTimeout(entry.getSocketTimeout());
+    }
+
+    @Override
+    protected void onRelease(final CPoolEntry entry) {
+        final NHttpClientConnection conn = entry.getConnection();
+        entry.setSocketTimeout(conn.getSocketTimeout());
+        conn.setSocketTimeout(0);
     }
 
 }
diff --git a/httpasyncclient/src/main/java/org/apache/http/impl/nio/conn/CPoolEntry.java b/httpasyncclient/src/main/java/org/apache/http/impl/nio/conn/CPoolEntry.java
index e40d99b..ffe7286 100644
--- a/httpasyncclient/src/main/java/org/apache/http/impl/nio/conn/CPoolEntry.java
+++ b/httpasyncclient/src/main/java/org/apache/http/impl/nio/conn/CPoolEntry.java
@@ -40,6 +40,7 @@
 class CPoolEntry extends PoolEntry<HttpRoute, ManagedNHttpClientConnection> {
 
     private final Log log;
+    private volatile int socketTimeout;
     private volatile boolean routeComplete;
 
     public CPoolEntry(
@@ -60,6 +61,14 @@
         this.routeComplete = true;
     }
 
+    public int getSocketTimeout() {
+        return this.socketTimeout;
+    }
+
+    public void setSocketTimeout(final int socketTimeout) {
+        this.socketTimeout = socketTimeout;
+    }
+
     public void closeConnection() throws IOException {
         final ManagedNHttpClientConnection conn = getConnection();
         conn.close();