Skip to content

Commit 045016e

Browse files
committed
DeferredResult accessors based on volatile fields for proper visibility
Issue: SPR-13451 (cherry picked from commit ae0d945)
1 parent df3c312 commit 045016e

File tree

1 file changed

+18
-17
lines changed

1 file changed

+18
-17
lines changed

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

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2015 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.
@@ -13,6 +13,7 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16+
1617
package org.springframework.web.context.request.async;
1718

1819
import java.util.PriorityQueue;
@@ -64,9 +65,9 @@ public class DeferredResult<T> {
6465

6566
private DeferredResultHandler resultHandler;
6667

67-
private Object result = RESULT_NONE;
68+
private volatile Object result = RESULT_NONE;
6869

69-
private boolean expired;
70+
private volatile boolean expired;
7071

7172

7273
/**
@@ -95,33 +96,34 @@ public DeferredResult(Long timeout, Object timeoutResult) {
9596
this.timeout = timeout;
9697
}
9798

99+
98100
/**
99101
* Return {@code true} if this DeferredResult is no longer usable either
100102
* because it was previously set or because the underlying request expired.
101-
* <p>
102-
* The result may have been set with a call to {@link #setResult(Object)},
103+
* <p>The result may have been set with a call to {@link #setResult(Object)},
103104
* or {@link #setErrorResult(Object)}, or as a result of a timeout, if a
104105
* timeout result was provided to the constructor. The request may also
105106
* expire due to a timeout or network error.
106107
*/
107108
public final boolean isSetOrExpired() {
108-
return ((this.result != RESULT_NONE) || this.expired);
109+
return (this.result != RESULT_NONE || this.expired);
109110
}
110111

111112
/**
112-
* @return {@code true} if the DeferredResult has been set.
113+
* Return {@code true} if the DeferredResult has been set.
113114
*/
114115
public boolean hasResult() {
115-
return this.result != RESULT_NONE;
116+
return (this.result != RESULT_NONE);
116117
}
117118

118119
/**
119-
* @return the result or {@code null} if the result wasn't set; since the result can
120-
* also be {@code null}, it is recommended to use {@link #hasResult()} first
121-
* to check if there is a result prior to calling this method.
120+
* Return the result, or {@code null} if the result wasn't set. Since the result
121+
* can also be {@code null}, it is recommended to use {@link #hasResult()} first
122+
* to check if there is a result prior to calling this method.
122123
*/
123124
public Object getResult() {
124-
return hasResult() ? this.result : null;
125+
Object resultToCheck = this.result;
126+
return (resultToCheck != RESULT_NONE ? resultToCheck : null);
125127
}
126128

127129
/**
@@ -162,12 +164,12 @@ public final void setResultHandler(DeferredResultHandler resultHandler) {
162164
Assert.notNull(resultHandler, "DeferredResultHandler is required");
163165
synchronized (this) {
164166
this.resultHandler = resultHandler;
165-
if ((this.result != RESULT_NONE) && (!this.expired)) {
167+
if (this.result != RESULT_NONE && !this.expired) {
166168
try {
167169
this.resultHandler.handleResult(this.result);
168170
}
169-
catch (Throwable t) {
170-
logger.trace("DeferredResult not handled", t);
171+
catch (Throwable ex) {
172+
logger.trace("DeferredResult not handled", ex);
171173
}
172174
}
173175
}
@@ -211,9 +213,9 @@ public boolean setErrorResult(Object result) {
211213
return setResultInternal(result);
212214
}
213215

216+
214217
final DeferredResultProcessingInterceptor getInterceptor() {
215218
return new DeferredResultProcessingInterceptorAdapter() {
216-
217219
@Override
218220
public <S> boolean handleTimeout(NativeWebRequest request, DeferredResult<S> deferredResult) {
219221
if (timeoutCallback != null) {
@@ -224,7 +226,6 @@ public <S> boolean handleTimeout(NativeWebRequest request, DeferredResult<S> def
224226
}
225227
return true;
226228
}
227-
228229
@Override
229230
public <S> void afterCompletion(NativeWebRequest request, DeferredResult<S> deferredResult) {
230231
synchronized (DeferredResult.this) {

0 commit comments

Comments
 (0)