Skip to content
Permalink
Browse files

UNDERTOW-1381 Don't actually complete() the async context until the t…

…hread has returned to the container
  • Loading branch information
stuartwdouglas committed Jul 19, 2018
1 parent 53e74ec commit 7f60713d8b3aeb9ce5713cda04a6397283605a5b
@@ -94,6 +94,7 @@
private final Deque<Runnable> asyncTaskQueue = new ArrayDeque<>();
private boolean processingAsyncTask = false;
private volatile boolean complete = false;
private volatile boolean completedBeforeInitialRequestDone = false;

public AsyncContextImpl(final HttpServerExchange exchange, final ServletRequest servletRequest, final ServletResponse servletResponse, final ServletRequestContext servletRequestContext, boolean requestSupplied, final AsyncContextImpl previousAsyncContext) {
this.exchange = exchange;
@@ -106,7 +107,6 @@ public AsyncContextImpl(final HttpServerExchange exchange, final ServletRequest
exchange.dispatch(SameThreadExecutor.INSTANCE, new Runnable() {
@Override
public void run() {
servletRequestContext.getOriginalRequest().setAsyncCancelled(false);
exchange.setDispatchExecutor(null);
initialRequestDone();
}
@@ -282,20 +282,14 @@ public synchronized void complete() {
}

public synchronized void completeInternal() {
servletRequestContext.getOriginalRequest().asyncRequestDispatched();
Thread currentThread = Thread.currentThread();
if (!initialRequestDone && currentThread == initiatingThread) {
servletRequestContext.getOriginalRequest().setAsyncCancelled(true);
//TODO: according to the spec we should delay this until the container initiated thread has returned?

onAsyncComplete();
completedBeforeInitialRequestDone = true;
if (dispatched) {
throw UndertowServletMessages.MESSAGES.asyncRequestAlreadyDispatched();
}
exchange.unDispatch();
dispatched = true;
initialRequestDone();
} else {
servletRequestContext.getOriginalRequest().asyncRequestDispatched();
if (currentThread == exchange.getIoThread()) {
//the thread safety semantics here are a bit weird.
//basically if we are doing async IO we can't do a dispatch here, as then the IO thread can be racing
@@ -313,6 +307,7 @@ public synchronized void completeInternal() {
UndertowLogger.REQUEST_IO_LOGGER.handleUnexpectedFailure(t);
}
} else {
servletRequestContext.getOriginalRequest().asyncRequestDispatched();
doDispatch(new Runnable() {
@Override
public void run() {
@@ -457,6 +452,10 @@ public void handleError(final Throwable error) {
*/
public synchronized void initialRequestDone() {
initialRequestDone = true;
if(completedBeforeInitialRequestDone) {
completeInternal();
dispatched = true;
}
if (previousAsyncContext != null) {
previousAsyncContext.onAsyncStart(this);
previousAsyncContext = null;
@@ -114,7 +114,6 @@
private Cookie[] cookies;
private List<Part> parts = null;
private volatile boolean asyncStarted = false;
private volatile boolean asyncCancelled = false;
private volatile AsyncContextImpl asyncContext = null;
private Map<String, Deque<String>> queryParameters;
private FormData parsedFormData;
@@ -1054,18 +1053,14 @@ public AsyncContext startAsync(final ServletRequest servletRequest, final Servle

@Override
public boolean isAsyncStarted() {
return asyncStarted || asyncCancelled;
return asyncStarted;
}

@Override
public boolean isAsyncSupported() {
return exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY).isAsyncSupported();
}

void setAsyncCancelled(boolean asyncCancelled) {
this.asyncCancelled = asyncCancelled;
}

@Override
public AsyncContextImpl getAsyncContext() {
if (!isAsyncStarted()) {

0 comments on commit 7f60713

Please sign in to comment.
You can’t perform that action at this time.