Skip to content

Commit

Permalink
Avoid thread pinning in SseEmitter write operations
Browse files Browse the repository at this point in the history
This commit changes the `synchronized` usage into a `ReentrantLock`, in
order to guard write operations with a construct that does not pin
virtual threads to the current platform thread on JDK21.

Closes gh-30996
  • Loading branch information
bclozel committed Aug 4, 2023
1 parent 9908967 commit 646fd3e
Showing 1 changed file with 13 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
Expand All @@ -36,12 +38,18 @@
* @author Rossen Stoyanchev
* @author Juergen Hoeller
* @author Sam Brannen
* @author Brian Clozel
* @since 4.2
*/
public class SseEmitter extends ResponseBodyEmitter {

private static final MediaType TEXT_PLAIN = new MediaType("text", "plain", StandardCharsets.UTF_8);

/**
* Guards access to write operations on the response.
*/
private final Lock writeLock = new ReentrantLock();

/**
* Create a new SseEmitter instance.
*/
Expand Down Expand Up @@ -122,9 +130,13 @@ public void send(Object object, @Nullable MediaType mediaType) throws IOExceptio
*/
public void send(SseEventBuilder builder) throws IOException {
Set<DataWithMediaType> dataToSend = builder.build();
synchronized (this) {
this.writeLock.lock();
try {
super.send(dataToSend);
}
finally {
this.writeLock.unlock();
}
}

@Override
Expand Down

0 comments on commit 646fd3e

Please sign in to comment.