Skip to content

Commit cf74b1b

Browse files
committed
Consistent result synchronization in WebAsyncManager
Issue: SPR-16571
1 parent 58a5138 commit cf74b1b

File tree

1 file changed

+17
-15
lines changed

1 file changed

+17
-15
lines changed

spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncManager.java

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -51,6 +51,7 @@
5151
* detected via {@link #hasConcurrentResult()}.
5252
*
5353
* @author Rossen Stoyanchev
54+
* @author Juergen Hoeller
5455
* @since 3.2
5556
* @see org.springframework.web.context.request.AsyncWebRequestInterceptor
5657
* @see org.springframework.web.servlet.AsyncHandlerInterceptor
@@ -76,15 +77,13 @@ public final class WebAsyncManager {
7677

7778
private AsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor(this.getClass().getSimpleName());
7879

79-
private Object concurrentResult = RESULT_NONE;
80+
private volatile Object concurrentResult = RESULT_NONE;
8081

81-
private Object[] concurrentResultContext;
82+
private volatile Object[] concurrentResultContext;
8283

83-
private final Map<Object, CallableProcessingInterceptor> callableInterceptors =
84-
new LinkedHashMap<>();
84+
private final Map<Object, CallableProcessingInterceptor> callableInterceptors = new LinkedHashMap<>();
8585

86-
private final Map<Object, DeferredResultProcessingInterceptor> deferredResultInterceptors =
87-
new LinkedHashMap<>();
86+
private final Map<Object, DeferredResultProcessingInterceptor> deferredResultInterceptors = new LinkedHashMap<>();
8887

8988

9089
/**
@@ -105,7 +104,7 @@ public final class WebAsyncManager {
105104
* {@code true}.
106105
* @param asyncWebRequest the web request to use
107106
*/
108-
public void setAsyncWebRequest(final AsyncWebRequest asyncWebRequest) {
107+
public void setAsyncWebRequest(AsyncWebRequest asyncWebRequest) {
109108
Assert.notNull(asyncWebRequest, "AsyncWebRequest must not be null");
110109
this.asyncWebRequest = asyncWebRequest;
111110
this.asyncWebRequest.addCompletionHandler(() -> asyncWebRequest.removeAttribute(
@@ -130,7 +129,7 @@ public void setTaskExecutor(AsyncTaskExecutor taskExecutor) {
130129
* processing of the concurrent result.
131130
*/
132131
public boolean isConcurrentHandlingStarted() {
133-
return ((this.asyncWebRequest != null) && this.asyncWebRequest.isAsyncStarted());
132+
return (this.asyncWebRequest != null && this.asyncWebRequest.isAsyncStarted());
134133
}
135134

136135
/**
@@ -232,8 +231,10 @@ public void registerDeferredResultInterceptors(DeferredResultProcessingIntercept
232231
* {@linkplain #getConcurrentResultContext() concurrentResultContext}.
233232
*/
234233
public void clearConcurrentResult() {
235-
this.concurrentResult = RESULT_NONE;
236-
this.concurrentResultContext = null;
234+
synchronized (WebAsyncManager.this) {
235+
this.concurrentResult = RESULT_NONE;
236+
this.concurrentResultContext = null;
237+
}
237238
}
238239

239240
/**
@@ -334,7 +335,7 @@ public void startCallableProcessing(final WebAsyncTask<?> webAsyncTask, Object..
334335

335336
private void setConcurrentResultAndDispatch(Object result) {
336337
synchronized (WebAsyncManager.this) {
337-
if (hasConcurrentResult()) {
338+
if (this.concurrentResult != RESULT_NONE) {
338339
return;
339340
}
340341
this.concurrentResult = result;
@@ -349,7 +350,6 @@ private void setConcurrentResultAndDispatch(Object result) {
349350
logger.debug("Concurrent result value [" + this.concurrentResult +
350351
"] - dispatching request to resume processing");
351352
}
352-
353353
this.asyncWebRequest.dispatch();
354354
}
355355

@@ -425,8 +425,10 @@ public void startDeferredResultProcessing(
425425
}
426426

427427
private void startAsyncProcessing(Object[] processingContext) {
428-
clearConcurrentResult();
429-
this.concurrentResultContext = processingContext;
428+
synchronized (WebAsyncManager.this) {
429+
this.concurrentResult = RESULT_NONE;
430+
this.concurrentResultContext = processingContext;
431+
}
430432
this.asyncWebRequest.startAsync();
431433

432434
if (logger.isDebugEnabled()) {

0 commit comments

Comments
 (0)