Synchronize in WebAsyncManager onError/onTimeout
On connection loss, in a race between application thread and onError callback trying to set the DeferredResult and dispatch, the onError callback must not exit until dispatch completes. Currently, it may do so because the DeferredResult has checks to bypasses locking or even trying to dispatch if result is already set. Closes gh-34192
This commit is contained in:
@@ -425,6 +425,11 @@ public final class WebAsyncManager {
|
||||
}
|
||||
try {
|
||||
interceptorChain.triggerAfterTimeout(this.asyncWebRequest, deferredResult);
|
||||
synchronized (WebAsyncManager.this) {
|
||||
// If application thread set the DeferredResult first in a race,
|
||||
// we must still not return until setConcurrentResultAndDispatch is done
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
setConcurrentResultAndDispatch(ex);
|
||||
@@ -437,6 +442,11 @@ public final class WebAsyncManager {
|
||||
}
|
||||
try {
|
||||
interceptorChain.triggerAfterError(this.asyncWebRequest, deferredResult, ex);
|
||||
synchronized (WebAsyncManager.this) {
|
||||
// If application thread set the DeferredResult first in a race,
|
||||
// we must still not return until setConcurrentResultAndDispatch is done
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Throwable interceptorEx) {
|
||||
setConcurrentResultAndDispatch(interceptorEx);
|
||||
|
||||
Reference in New Issue
Block a user