Avoid thread pinning in SseEmitter write operations
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
This commit is contained in:
parent
9908967954
commit
646fd3edcc
|
@ -21,6 +21,8 @@ import java.nio.charset.StandardCharsets;
|
|||
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;
|
||||
|
@ -36,12 +38,18 @@ import org.springframework.util.StringUtils;
|
|||
* @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.
|
||||
*/
|
||||
|
@ -122,9 +130,13 @@ public class SseEmitter extends ResponseBodyEmitter {
|
|||
*/
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue