Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[UNDERTOW-2304] Prevent repeating SslConduit.doUnwrap when running hanshake task #1517

Merged
merged 1 commit into from
Feb 13, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions core/src/main/java/io/undertow/protocols/ssl/SslConduit.java
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,9 @@ public void run() {
this.sink = delegate.getSinkChannel().getConduit();
this.source = delegate.getSourceChannel().getConduit();
this.engine = engine;
this.delegatedTaskExecutor = delegatedTaskExecutor;
// if delegatedTaskExecutor is the same as delegate.getWorker, don't set it (see handshake task execution below,
// we need to pick a thread that is different from the current thread running or run the handshake task immediately at the same thread)
this.delegatedTaskExecutor = this.delegate.getWorker() != delegatedTaskExecutor? delegatedTaskExecutor : null;
this.bufferPool = bufferPool;
delegate.getSourceChannel().getConduit().setReadReadyHandler(readReadyHandler = new SslReadReadyHandler(null));
delegate.getSinkChannel().getConduit().setWriteReadyHandler(writeReadyHandler = new SslWriteReadyHandler(null));
Expand Down Expand Up @@ -1173,7 +1175,16 @@ public void run() {
}
};
try {
getDelegatedTaskExecutor().execute(wrappedTask);
// we want to pick a thread different from the one we are running, to prevent starvation scenarios
// for example where we repeatedly attempt to write or read but are stuck waiting on a handshake task
// and the handshake task rarely has the chance to run because it needs the read/write thread to complete execution
// so, if io thread (read and write thread) is the same as current thread, and getDelegatedTaskExecutor will delegate
// execution to the same set of threads we are currently at, just run the handshake task right away to prevent blocking
if (delegate.getIoThread().equals(Thread.currentThread()) && delegatedTaskExecutor == null) {
wrappedTask.run();
} else {
getDelegatedTaskExecutor().execute(wrappedTask);
}
} catch (RejectedExecutionException e) {
UndertowLogger.REQUEST_IO_LOGGER.sslEngineDelegatedTaskRejected(e);
IoUtils.safeClose(connection);
Expand Down
Loading