fix: address CodeQL concurrency warnings - #19827
Conversation
There was a problem hiding this comment.
🟡 Not ready to approve
notifyAll() in AppendableByteArrayInputStream.add() can enable concurrent readers to proceed and race on shared read state, and the MapDB manager changes need small follow-ups for lock scope and final field consistency.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.
Pull request overview
This PR updates several synchronization points to address CodeQL concurrency warnings (notify vs notifyAll, and a TOCTOU check/use pattern around MapDB lifecycle) in Druid’s processing and lookup-cache components.
Changes:
- Switch monitor signaling from
notify()tonotifyAll()in stream/channel paths to ensure terminal transitions (and chunk/backpressure transitions) don’t leave additional waiters blocked. - Add tests proving
AppendableByteArrayInputStreamterminal transitions (done,exceptionCaught) unblock multiple waiting readers. - Synchronize MapDB “check then use” sequences (
isClosed()+delete/close) on theDBinstance monitor.
File summaries
| File | Description |
|---|---|
processing/src/test/java/org/apache/druid/java/util/http/client/io/AppendableByteArrayInputStreamTest.java |
Adds multi-reader blocking/unblock tests for done() and exceptionCaught(). |
processing/src/main/java/org/apache/druid/java/util/http/client/io/AppendableByteArrayInputStream.java |
Changes monitor notification to notifyAll() in producer/terminal methods. |
processing/src/main/java/org/apache/druid/frame/channel/ReadableInputStreamFrameChannel.java |
Uses notifyAll() when releasing backpressure waiters on readMonitor. |
extensions-core/lookups-cached-global/src/main/java/org/apache/druid/server/lookup/namespace/cache/OffHeapNamespaceExtractionCacheManager.java |
Synchronizes MapDB check/use sequences on the DB instance and documents the rationale. |
Review details
Comments suppressed due to low confidence (1)
extensions-core/lookups-cached-global/src/main/java/org/apache/druid/server/lookup/namespace/cache/OffHeapNamespaceExtractionCacheManager.java:162
- Per the project code style (“Always use
finalfor fields and variables that are not reassigned”, seeAGENTS.md:40), these atomic field references should befinalsince they are never reassigned.
private final DB mmapDB;
private final File tmpFile;
private AtomicLong mapDbKeyCounter = new AtomicLong(0);
private AtomicInteger cacheCount = new AtomicInteger(0);
- Files reviewed: 4/4 changed files
- Comments generated: 2
- Review effort level: Low
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
There was a problem hiding this comment.
🟢 Ready to approve
The concurrency fixes are narrowly scoped, align with the PR’s stated CodeQL goals, and are supported by targeted multi-waiter tests for the terminal stream transitions.
This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.
Review details
- Files reviewed: 4/4 changed files
- Comments generated: 0 new
- Review effort level: Lite
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
What
Why
This addresses all five CodeQL warnings in the concurrency group:
java/notify-instead-of-notify-alljava/toctou-race-conditionImpact
Terminal input-stream transitions can no longer leave additional readers blocked. MapDB close and cache disposal cannot interleave between
isClosed()and the corresponding state-changing operation.Root cause
The stream implementations relied on an implicit single-waiter assumption. The MapDB lifecycle method was synchronized on the anonymous handler instance rather than on the database object used by MapDB's own synchronized APIs.
Checks
git diff --checkCreated by GPT-5.6-Sol.