[#857] Iterate a snapshot of the connection set in AuthenticatedUsers.doPostResponse(modify) - #858
Merged
vharseko merged 1 commit intoAug 10, 2026
Conversation
…n AuthenticatedUsers.doPostResponse(modify) updateAuthenticationInfo() re-registers the connection (remove + put), appending it back to the tail of the live set's hash-bin chain; a weakly-consistent iterator over the set itself then meets the connection again and, with two or more connections in one bin, ping-pongs between them forever, hanging the bind that triggered the internal modify (seen in CI as the PasswordPolicyTestCase.testResetWithLastLoginTime timeout). Regression of OpenIdentityPlatform#660, which replaced the CopyOnWriteArraySet snapshot iteration under the global write lock with direct iteration of the live concurrent set. Add a regression test that pins two colliding connections into one bin and reproduces the livelock deterministically.
maximthomas
approved these changes
Aug 10, 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 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.
Fixes #857.
Problem
AuthenticatedUsers.doPostResponse(PostResponseModifyOperation)iterates the live per-user connection set (ConcurrentHashMap.newKeySet()), whileupdateAuthenticationInfo()→setAuthenticationInfo()re-registers each visited connection (remove+put) into that same set. The re-inserted node is appended to the tail of its hash-bin chain and the removed node keeps itsnextpointer, so the weakly-consistent iterator meets the connection again; with two or more connections in one bin the loop ping-pongs between them forever. The worker thread spinsRUNNABLEand the bind that triggered the internal modify (password-policy last-login-time update) never gets a response — seen in CI as thePasswordPolicyTestCase.testResetWithLastLoginTime600 s timeout.Regression of #660: before it, the loop iterated a
CopyOnWriteArraySetsnapshot under the reentrant global write lock, so the nested remove/put could not affect the iteration. Both protections were removed together.Fix
Iterate a snapshot (
connectionSet.toArray(new ClientConnection[0])) instead of the live set — restores the copy-on-write iteration semantics while keeping registration lock-free. The delete/modifyDN paths are not affected: their sets are detached from the map first viaremoveSubtree.Regression test
AuthenticatedUsersTestCaseregisters two connections with a constanthashCode()(forcing both into one bin of the connection set) under the same user DN and drivesdoPostResponse(modify)directly:ThreadTimeoutException ... 600000signature as the CI hang;