Skip to content

[#816] Unmap only the locked domainMap in FileChangelogDB.removeDomain() - #827

Merged
vharseko merged 1 commit into
OpenIdentityPlatform:masterfrom
vharseko:issues/816-filechangelogdb-removedomain-npe
Aug 4, 2026
Merged

[#816] Unmap only the locked domainMap in FileChangelogDB.removeDomain()#827
vharseko merged 1 commit into
OpenIdentityPlatform:masterfrom
vharseko:issues/816-filechangelogdb-removedomain-npe

Conversation

@vharseko

@vharseko vharseko commented Aug 3, 2026

Copy link
Copy Markdown
Member

Fixes #816.

FileChangelogDB.removeDomain() reassigned the local variable whose monitor it was holding: a racing shutdownDB() drain, clearDB() or a concurrent removeDomain() made domainToReplicaDBs.remove(baseDN) return null, and the next line threw NullPointerException instead of the ChangelogException callers such as ReplicationServerDomain.clearDbs() handle.

The entry is now removed only while it still maps the instance the monitor was taken on (an identity check under that monitor, which is what makes the check-then-remove atomic: every remover takes the same monitor before unmapping), and iteration stays on that instance:

  • replica DBs a concurrent remover already visited are cleared and shut down again harmlessly — Log.clear() returns at once on a closed log and FileReplicaDB.shutdown() is CAS-guarded;
  • a domainMap concurrently recreated for the same baseDN by getOrCreateReplicaDB() is left untouched instead of being unmapped while holding the wrong monitor.

The new FileChangelogDBTest reproduces both windows deterministically: it holds the domainMap monitor, waits via ThreadMXBean until removeDomain() blocks on exactly that monitor, and simulates the concurrent remover inside the window. Both tests fail on the unfixed code — removeDomainRacingConcurrentRemovalMustNotThrowNPE with the exact NPE from the issue — and pass with the fix.

…ngelogDB.removeDomain()

removeDomain() reassigned the local variable whose monitor it was holding:
a racing shutdownDB() drain, clearDB() or concurrent removeDomain() made
domainToReplicaDBs.remove(baseDN) return null and the next line threw
NullPointerException instead of the ChangelogException callers handle.
Remove the entry only while it still maps the instance the monitor was
taken on, and keep iterating that instance: replica DBs a concurrent
remover already visited are cleared and shut down again harmlessly, and
a domainMap recreated for the same baseDN is left untouched.
@vharseko vharseko added bug replication concurrency Thread-safety / race-condition bugs tests Test suites: fixing, enabling, un-disabling labels Aug 3, 2026
@vharseko
vharseko requested a review from maximthomas August 3, 2026 12:40
@vharseko
vharseko merged commit 4f4d184 into OpenIdentityPlatform:master Aug 4, 2026
17 checks passed
@vharseko
vharseko deleted the issues/816-filechangelogdb-removedomain-npe branch August 4, 2026 08:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug concurrency Thread-safety / race-condition bugs replication tests Test suites: fixing, enabling, un-disabling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FileChangelogDB.removeDomain() throws NullPointerException when it races shutdownDB()

2 participants