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();