From 58ff213430421962d7ca99420494e1525343cdb3 Mon Sep 17 00:00:00 2001 From: Stuart Douglas Date: Thu, 19 Aug 2021 13:45:18 +1000 Subject: [PATCH] Fix RESTEasy Reactive race These executor dispatch has to be the last thing in the method, to prevent a possible race Fixes #19471 (cherry picked from commit b361dbe92322bf8e70ae70afb28a07a99689be8c) --- .../core/AbstractResteasyReactiveContext.java | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/core/AbstractResteasyReactiveContext.java b/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/core/AbstractResteasyReactiveContext.java index 5af64f58d38d4..d84d27bb11bbf 100644 --- a/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/core/AbstractResteasyReactiveContext.java +++ b/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/core/AbstractResteasyReactiveContext.java @@ -125,6 +125,8 @@ public void run() { //if this is a blocking target we don't activate for the initial non-blocking part //unless there are pre-mapping filters as these may require CDI boolean disasociateRequestScope = false; + boolean aborted = false; + Executor exec = null; try { while (position < handlers.length) { int pos = position; @@ -132,7 +134,6 @@ public void run() { try { handlers[pos].handle((T) this); if (suspended) { - Executor exec = null; synchronized (this) { if (isRequestScopeManagementRequired()) { if (requestScopeActivated) { @@ -151,40 +152,29 @@ public void run() { exec = this.executor; // prevent future suspensions from re-submitting the task this.executor = null; + return; } else if (suspended) { running = false; processingSuspended = true; return; } } - if (exec != null) { - //outside sync block - exec.execute(this); - processingSuspended = true; - return; - } } } catch (Throwable t) { - boolean over = handlers == abortHandlerChain; + aborted = handlers == abortHandlerChain; if (t instanceof PreserveTargetException) { handleException(t.getCause(), true); } else { handleException(t); } - if (over) { - running = false; - return; - } } } - running = false; } catch (Throwable t) { handleUnrecoverableError(t); - running = false; } finally { // we need to make sure we don't close the underlying stream in the event loop if the task // has been offloaded to the executor - if (position == handlers.length && !processingSuspended) { + if ((position == handlers.length && !processingSuspended) || aborted) { close(); } else { if (disasociateRequestScope) { @@ -193,6 +183,13 @@ public void run() { } beginAsyncProcessing(); } + synchronized (this) { + running = false; + } + if (exec != null) { + //outside sync block + exec.execute(this); + } } }