2121import java .util .LinkedHashSet ;
2222import java .util .List ;
2323import java .util .Set ;
24- import java .util .concurrent .atomic .AtomicBoolean ;
2524import java .util .function .Consumer ;
2625
2726import org .springframework .http .MediaType ;
@@ -77,7 +76,7 @@ public class ResponseBodyEmitter {
7776 private final Set <DataWithMediaType > earlySendAttempts = new LinkedHashSet <>(8 );
7877
7978 /** Store successful completion before the handler is initialized. */
80- private final AtomicBoolean complete = new AtomicBoolean () ;
79+ private boolean complete ;
8180
8281 /** Store an error before the handler is initialized. */
8382 @ Nullable
@@ -128,7 +127,7 @@ synchronized void initialize(Handler handler) throws IOException {
128127 this .earlySendAttempts .clear ();
129128 }
130129
131- if (this .complete . get () ) {
130+ if (this .complete ) {
132131 if (this .failure != null ) {
133132 this .handler .completeWithError (this .failure );
134133 }
@@ -143,12 +142,11 @@ synchronized void initialize(Handler handler) throws IOException {
143142 }
144143 }
145144
146- void initializeWithError (Throwable ex ) {
147- if (this .complete .compareAndSet (false , true )) {
148- this .failure = ex ;
149- this .earlySendAttempts .clear ();
150- this .errorCallback .accept (ex );
151- }
145+ synchronized void initializeWithError (Throwable ex ) {
146+ this .complete = true ;
147+ this .failure = ex ;
148+ this .earlySendAttempts .clear ();
149+ this .errorCallback .accept (ex );
152150 }
153151
154152 /**
@@ -186,7 +184,7 @@ public void send(Object object) throws IOException {
186184 * @throws java.lang.IllegalStateException wraps any other errors
187185 */
188186 public synchronized void send (Object object , @ Nullable MediaType mediaType ) throws IOException {
189- Assert .state (!this .complete . get () , () -> "ResponseBodyEmitter has already completed" +
187+ Assert .state (!this .complete , () -> "ResponseBodyEmitter has already completed" +
190188 (this .failure != null ? " with error: " + this .failure : "" ));
191189 if (this .handler != null ) {
192190 try {
@@ -214,7 +212,7 @@ public synchronized void send(Object object, @Nullable MediaType mediaType) thro
214212 * @since 6.0.12
215213 */
216214 public synchronized void send (Set <DataWithMediaType > items ) throws IOException {
217- Assert .state (!this .complete . get () , () -> "ResponseBodyEmitter has already completed" +
215+ Assert .state (!this .complete , () -> "ResponseBodyEmitter has already completed" +
218216 (this .failure != null ? " with error: " + this .failure : "" ));
219217 sendInternal (items );
220218 }
@@ -247,8 +245,9 @@ private void sendInternal(Set<DataWithMediaType> items) throws IOException {
247245 * to complete request processing. It should not be used after container
248246 * related events such as an error while {@link #send(Object) sending}.
249247 */
250- public void complete () {
251- if (this .complete .compareAndSet (false , true ) && this .handler != null ) {
248+ public synchronized void complete () {
249+ this .complete = true ;
250+ if (this .handler != null ) {
252251 this .handler .complete ();
253252 }
254253 }
@@ -264,12 +263,11 @@ public void complete() {
264263 * container related events such as an error while
265264 * {@link #send(Object) sending}.
266265 */
267- public void completeWithError (Throwable ex ) {
268- if (this .complete .compareAndSet (false , true )) {
269- this .failure = ex ;
270- if (this .handler != null ) {
271- this .handler .completeWithError (ex );
272- }
266+ public synchronized void completeWithError (Throwable ex ) {
267+ this .complete = true ;
268+ this .failure = ex ;
269+ if (this .handler != null ) {
270+ this .handler .completeWithError (ex );
273271 }
274272 }
275273
@@ -278,7 +276,7 @@ public void completeWithError(Throwable ex) {
278276 * called from a container thread when an async request times out.
279277 * <p>As of 6.2, one can register multiple callbacks for this event.
280278 */
281- public void onTimeout (Runnable callback ) {
279+ public synchronized void onTimeout (Runnable callback ) {
282280 this .timeoutCallback .addDelegate (callback );
283281 }
284282
@@ -289,7 +287,7 @@ public void onTimeout(Runnable callback) {
289287 * <p>As of 6.2, one can register multiple callbacks for this event.
290288 * @since 5.0
291289 */
292- public void onError (Consumer <Throwable > callback ) {
290+ public synchronized void onError (Consumer <Throwable > callback ) {
293291 this .errorCallback .addDelegate (callback );
294292 }
295293
@@ -300,7 +298,7 @@ public void onError(Consumer<Throwable> callback) {
300298 * detecting that a {@code ResponseBodyEmitter} instance is no longer usable.
301299 * <p>As of 6.2, one can register multiple callbacks for this event.
302300 */
303- public void onCompletion (Runnable callback ) {
301+ public synchronized void onCompletion (Runnable callback ) {
304302 this .completionCallback .addDelegate (callback );
305303 }
306304
@@ -371,15 +369,15 @@ public MediaType getMediaType() {
371369
372370 private class DefaultCallback implements Runnable {
373371
374- private final List <Runnable > delegates = new ArrayList <>(1 );
372+ private List <Runnable > delegates = new ArrayList <>(1 );
375373
376- public synchronized void addDelegate (Runnable delegate ) {
374+ public void addDelegate (Runnable delegate ) {
377375 this .delegates .add (delegate );
378376 }
379377
380378 @ Override
381379 public void run () {
382- ResponseBodyEmitter .this .complete . compareAndSet ( false , true ) ;
380+ ResponseBodyEmitter .this .complete = true ;
383381 for (Runnable delegate : this .delegates ) {
384382 delegate .run ();
385383 }
@@ -389,15 +387,15 @@ public void run() {
389387
390388 private class ErrorCallback implements Consumer <Throwable > {
391389
392- private final List <Consumer <Throwable >> delegates = new ArrayList <>(1 );
390+ private List <Consumer <Throwable >> delegates = new ArrayList <>(1 );
393391
394- public synchronized void addDelegate (Consumer <Throwable > callback ) {
392+ public void addDelegate (Consumer <Throwable > callback ) {
395393 this .delegates .add (callback );
396394 }
397395
398396 @ Override
399397 public void accept (Throwable t ) {
400- ResponseBodyEmitter .this .complete . compareAndSet ( false , true ) ;
398+ ResponseBodyEmitter .this .complete = true ;
401399 for (Consumer <Throwable > delegate : this .delegates ) {
402400 delegate .accept (t );
403401 }
0 commit comments