Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[UNDERTOW-2338] Use a lock when setting the AsyncContext and asyncSta… #1546

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


/**
Expand All @@ -110,6 +112,7 @@ public final class HttpServletRequestImpl implements HttpServletRequest {

private final HttpServerExchange exchange;
private final ServletContextImpl originalServletContext;
private final Lock asyncContextLock;
private ServletContextImpl servletContext;

private Map<String, Object> attributes = null;
Expand All @@ -119,8 +122,10 @@ public final class HttpServletRequestImpl implements HttpServletRequest {

private Cookie[] cookies;
private List<Part> parts = null;
private volatile boolean asyncStarted = false;
private volatile AsyncContextImpl asyncContext = null;
// Guarded by asyncContextLock
private boolean asyncStarted = false;
// Guarded by asyncContextLock
private AsyncContextImpl asyncContext = null;
private Map<String, Deque<String>> queryParameters;
private FormData parsedFormData;
private RuntimeException formParsingException;
Expand All @@ -132,6 +137,7 @@ public HttpServletRequestImpl(final HttpServerExchange exchange, final ServletCo
this.exchange = exchange;
this.servletContext = servletContext;
this.originalServletContext = servletContext;
asyncContextLock = new ReentrantLock();
}

public HttpServerExchange getExchange() {
Expand Down Expand Up @@ -1072,12 +1078,18 @@ public ServletContextImpl getServletContext() {
public AsyncContext startAsync() throws IllegalStateException {
if (!isAsyncSupported()) {
throw UndertowServletMessages.MESSAGES.startAsyncNotAllowed();
} else if (asyncStarted) {
throw UndertowServletMessages.MESSAGES.asyncAlreadyStarted();
}
asyncStarted = true;
final ServletRequestContext servletRequestContext = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
return asyncContext = new AsyncContextImpl(exchange, servletRequestContext.getServletRequest(), servletRequestContext.getServletResponse(), servletRequestContext, false, asyncContext);
try {
asyncContextLock.lock();
if (asyncStarted) {
throw UndertowServletMessages.MESSAGES.asyncAlreadyStarted();
}
asyncStarted = true;
final ServletRequestContext servletRequestContext = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
return asyncContext = new AsyncContextImpl(exchange, servletRequestContext.getServletRequest(), servletRequestContext.getServletResponse(), servletRequestContext, false, asyncContext);
} finally {
asyncContextLock.unlock();
}
}

@Override
Expand All @@ -1097,18 +1109,29 @@ public AsyncContext startAsync(final ServletRequest servletRequest, final Servle
}
if (!isAsyncSupported()) {
throw UndertowServletMessages.MESSAGES.startAsyncNotAllowed();
} else if (asyncStarted) {
throw UndertowServletMessages.MESSAGES.asyncAlreadyStarted();
}
asyncStarted = true;
servletRequestContext.setServletRequest(servletRequest);
servletRequestContext.setServletResponse(servletResponse);
return asyncContext = new AsyncContextImpl(exchange, servletRequest, servletResponse, servletRequestContext, true, asyncContext);
try {
asyncContextLock.lock();
if (asyncStarted) {
throw UndertowServletMessages.MESSAGES.asyncAlreadyStarted();
}
asyncStarted = true;
servletRequestContext.setServletRequest(servletRequest);
servletRequestContext.setServletResponse(servletResponse);
return asyncContext = new AsyncContextImpl(exchange, servletRequest, servletResponse, servletRequestContext, true, asyncContext);
} finally {
asyncContextLock.unlock();
}
}

@Override
public boolean isAsyncStarted() {
return asyncStarted;
try {
asyncContextLock.lock();
return asyncStarted;
} finally {
asyncContextLock.unlock();
}
}

@Override
Expand All @@ -1121,11 +1144,21 @@ public AsyncContextImpl getAsyncContext() {
if (!isAsyncStarted()) {
throw UndertowServletMessages.MESSAGES.asyncNotStarted();
}
return asyncContext;
try {
asyncContextLock.lock();
return asyncContext;
} finally {
asyncContextLock.unlock();
}
}

public AsyncContextImpl getAsyncContextInternal() {
return asyncContext;
try {
asyncContextLock.lock();
return asyncContext;
} finally {
asyncContextLock.unlock();
}
}

@Override
Expand All @@ -1150,7 +1183,12 @@ public void setServletContext(final ServletContextImpl servletContext) {
}

void asyncRequestDispatched() {
asyncStarted = false;
try {
asyncContextLock.lock();
asyncStarted = false;
} finally {
asyncContextLock.unlock();
}
}

public String getOriginalRequestURI() {
Expand Down
Loading