Skip to content

Commit 9c13c6b

Browse files
committed
Revert "Use optimistic locking where possible in ResponseBodyEmitter"
This reverts commit e67f892. Closes gh-34762
1 parent b49924b commit 9c13c6b

File tree

1 file changed

+26
-28
lines changed

1 file changed

+26
-28
lines changed

Diff for: spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitter.java

+26-28
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import java.util.LinkedHashSet;
2222
import java.util.List;
2323
import java.util.Set;
24-
import java.util.concurrent.atomic.AtomicBoolean;
2524
import java.util.function.Consumer;
2625

2726
import 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

Comments
 (0)