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 2019/08/20 06:57:56 UTC

[httpcomponents-core] 01/01: HTTPASYNC-152: minimize possibility of a race condition when I/O reactor session request gets cancelled ot times out immediately after its creation

This is an automated email from the ASF dual-hosted git repository.

olegk pushed a commit to branch HTTPASYNC-152
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git

commit aa9d7cbe0d2249c2c3d2b5f1073d5db04e2f7da5
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Mon Aug 19 14:46:43 2019 +0200

    HTTPASYNC-152: minimize possibility of a race condition when I/O reactor session request gets cancelled ot times out immediately after its creation
---
 .../http/impl/nio/reactor/AbstractIOReactor.java   | 24 +++++++++++++++++-----
 .../http/impl/nio/reactor/BaseIOReactor.java       | 12 +++++------
 .../http/impl/nio/reactor/SessionRequestImpl.java  |  8 ++++++++
 3 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractIOReactor.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractIOReactor.java
index b0c150b..d84faeb 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractIOReactor.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/AbstractIOReactor.java
@@ -419,14 +419,23 @@ public abstract class AbstractIOReactor implements IOReactor {
             }
             try {
                 this.sessions.add(session);
+                key.attach(session);
                 final SessionRequestImpl sessionRequest = entry.getSessionRequest();
                 if (sessionRequest != null) {
-                    sessionRequest.completed(session);
+                    if (!sessionRequest.isTerminated()) {
+                        sessionRequest.completed(session);
+                    }
+                    if (!sessionRequest.isTerminated()) {
+                        sessionCreated(key, session);
+                    }
+                    if (sessionRequest.isTerminated()) {
+                        throw new CancelledKeyException();
+                    }
+                } else {
+                    sessionCreated(key, session);
                 }
-                key.attach(session);
-                sessionCreated(key, session);
             } catch (final CancelledKeyException ex) {
-                queueClosedSession(session);
+                session.close();
                 key.attach(null);
             }
         }
@@ -489,7 +498,12 @@ public abstract class AbstractIOReactor implements IOReactor {
             final int timeout = session.getSocketTimeout();
             if (timeout > 0) {
                 if (session.getLastAccessTime() + timeout < now) {
-                    sessionTimedOut(session);
+                    try {
+                        sessionTimedOut(session);
+                    } catch (final CancelledKeyException ex) {
+                        session.close();
+                        key.attach(null);
+                    }
                 }
             }
         }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/BaseIOReactor.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/BaseIOReactor.java
index 32d37db..c9caef2 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/BaseIOReactor.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/BaseIOReactor.java
@@ -169,8 +169,7 @@ public class BaseIOReactor extends AbstractIOReactor {
                 this.bufferingSessions.add(session);
             }
         } catch (final CancelledKeyException ex) {
-            queueClosedSession(session);
-            key.attach(null);
+            throw ex;
         } catch (final RuntimeException ex) {
             handleRuntimeException(ex);
         }
@@ -187,8 +186,7 @@ public class BaseIOReactor extends AbstractIOReactor {
         try {
             this.eventDispatch.outputReady(session);
         } catch (final CancelledKeyException ex) {
-            queueClosedSession(session);
-            key.attach(null);
+            throw ex;
         } catch (final RuntimeException ex) {
             handleRuntimeException(ex);
         }
@@ -230,7 +228,7 @@ public class BaseIOReactor extends AbstractIOReactor {
                     }
                 } catch (final CancelledKeyException ex) {
                     it.remove();
-                    queueClosedSession(session);
+                    session.close();
                 } catch (final RuntimeException ex) {
                     handleRuntimeException(ex);
                 }
@@ -247,7 +245,7 @@ public class BaseIOReactor extends AbstractIOReactor {
         try {
             this.eventDispatch.connected(session);
         } catch (final CancelledKeyException ex) {
-            queueClosedSession(session);
+            throw ex;
         } catch (final RuntimeException ex) {
             handleRuntimeException(ex);
         }
@@ -262,7 +260,7 @@ public class BaseIOReactor extends AbstractIOReactor {
         try {
             this.eventDispatch.timeout(session);
         } catch (final CancelledKeyException ex) {
-            queueClosedSession(session);
+            throw ex;
         } catch (final RuntimeException ex) {
             handleRuntimeException(ex);
         }
diff --git a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SessionRequestImpl.java b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SessionRequestImpl.java
index 94e57c0..bb45315 100644
--- a/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SessionRequestImpl.java
+++ b/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SessionRequestImpl.java
@@ -56,6 +56,7 @@ public class SessionRequestImpl implements SessionRequest {
 
     private volatile SelectionKey key;
 
+    private volatile boolean terminated;
     private volatile int connectTimeout;
     private volatile IOSession session = null;
     private volatile IOException exception = null;
@@ -94,6 +95,10 @@ public class SessionRequestImpl implements SessionRequest {
         return this.completed.get();
     }
 
+    boolean isTerminated() {
+        return this.terminated;
+    }
+
     protected void setKey(final SelectionKey key) {
         this.key = key;
     }
@@ -142,6 +147,7 @@ public class SessionRequestImpl implements SessionRequest {
             return;
         }
         if (this.completed.compareAndSet(false, true)) {
+            this.terminated = true;
             final SelectionKey key = this.key;
             if (key != null) {
                 key.cancel();
@@ -162,6 +168,7 @@ public class SessionRequestImpl implements SessionRequest {
 
     public void timeout() {
         if (this.completed.compareAndSet(false, true)) {
+            this.terminated = true;
             final SelectionKey key = this.key;
             if (key != null) {
                 key.cancel();
@@ -199,6 +206,7 @@ public class SessionRequestImpl implements SessionRequest {
     @Override
     public void cancel() {
         if (this.completed.compareAndSet(false, true)) {
+            this.terminated = true;
             final SelectionKey key = this.key;
             if (key != null) {
                 key.cancel();