Uh oh!
There was an error while loading. Please reload this page.
Fix race in BatchApiOpImpl CompletionListener.start() causing flaky IllegalThreadStateException (#105) - #106
Merged
vharseko merged 1 commit intoJul 20, 2026
Conversation
…atform#105) Two response-dispatch pool threads (batch-token and "complete" branches of handleOperationResponseMessages) could both observe running == false and both call Thread.start(), throwing IllegalThreadStateException and losing the batch result. Guard the start with an AtomicBoolean CAS. Also make returnToken volatile and publish it fully populated, so the CompletionListener thread never spins on a stale null or observes a partially built token when it lost the start() race.
maximthomas
approved these changes
Jul 20, 2026
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 freeto 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.
Fixes#105.
Problem
AsyncRemoteSecureConnectorInfoManagerTest.testSerialBatchWithErrorfails intermittently in CI withIllegalThreadStateExceptionthrown fromBatchApiOpImpl$InternalRequest$CompletionListener.start().CompletionListener.start()guardedThread.start()with a plain, unsynchronizedboolean. The listener is started from two branches ofhandleOperationResponseMessages— the batch-token branch and the "complete" branch — and operation responses are dispatched on a thread pool, so when the token and complete messages arrive close together, two pool threads can both observerunning == falseand both callsuper.start()(check-then-act race). The secondThread.start()throws, the exception propagates out of the message-processing task, and the batch result is lost.Fix
AtomicBooleanCAS — only the first caller may actually start the thread.returnTokenvolatileand publish it fully populated (build in a local, assign last): theCompletionListenerthread spins onreturnToken == null, and when it lost thestart()race there was no happens-before edge, so it could observe a stalenullor a partially built token.Testing
AsyncRemoteSecureConnectorInfoManagerTest(connector-server-grizzly, includestestSerialBatchWithError) run 4 times locally:Tests run: 14, Failures: 0, Errors: 0each time.