Complete I/O reactor termination when the selector has been closed by another thread - #718
Merged
Merged
Conversation
… another thread closeOpenChannels threw ClosedSelectorException once close(CloseMode) from another thread had closed the selector, so doTerminate reported it through the exception callback and skipped processClosedSessions: event handlers of the closed sessions were never notified of the disconnect.
Member
|
@AdzerKI Cherry-picked to |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
We hit this with HttpClient 5 talking to a TLS 1.3 server that does not answer close_notify (JDK default,
jdk.tls.acknowledgeCloseNotify=false).CloseableHttpAsyncClient#close()waits for the graceful shutdown, gives up after 5 seconds, andMultiCoreIOReactorthen closes eachSingleCoreIOReactorwithCloseMode.IMMEDIATEfrom the calling thread. That closes the selector while the I/O dispatch thread is still running. ItsdoTerminatecallscloseOpenChannels,selector.keys()throws, and the defaultLoggingExceptionCallbacklogs an ERROR on every client shutdown:The exception also skips
processClosedSessions, so the handlers of sessions closed byclose(CloseMode)never getdisconnected.By then
close(CloseMode)has already closed the registered channels, socloseOpenChannelsnow just returns when the selector is closed and termination goes on.doExecutealready ignoresClosedSelectorExceptionfor the same reason.Test:
TestSingleCoreIOReactor#terminatesWhenSelectorClosedByAnotherThreadholds the dispatch thread inconnected, closes the reactor from the test thread, then lets the dispatch thread go. It expects no reported exception and adisconnectedcall. Fails on master withClosedSelectorException, passes with the fix;httpcore5builds with all tests.The same code is on 5.4.x (the stack trace above is from 5.4.3).