This is an automated email from the ASF dual-hosted git repository.
jxue pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/helix.git
The following commit(s) were added to refs/heads/master by this push:
new aba2b54bb Fix racecondition in PerKeyBlockingExecutor
aba2b54bb is described below
commit aba2b54bb9c6c6ba7e45f4e35f6027b953c5bd40
Author: Junkai Xue <[email protected]>
AuthorDate: Sat Mar 7 20:24:53 2026 -0800
Fix racecondition in PerKeyBlockingExecutor
The original code had a race condition:
1. offerEvent checks _runningEvents.contains(key) to decide whether to
queue or execute
2. But the key was only added to _runningEvents inside runEvent() which
runs in a separate executor thread
3. This created a window where the second event could be executed
directly instead of being queued, because _runningEvents didn't have the key
yet when the check happened
Fix: Move _runningEvents.add(key) to execute BEFORE the executor submits
the task (inside the lock), ensuring the key is marked as running before any
subsequent offerEvent calls for the same key can
check the set.
---
.../java/org/apache/helix/gateway/util/PerKeyBlockingExecutor.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git
a/helix-gateway/src/main/java/org/apache/helix/gateway/util/PerKeyBlockingExecutor.java
b/helix-gateway/src/main/java/org/apache/helix/gateway/util/PerKeyBlockingExecutor.java
index c5463d214..b8a342b2d 100644
---
a/helix-gateway/src/main/java/org/apache/helix/gateway/util/PerKeyBlockingExecutor.java
+++
b/helix-gateway/src/main/java/org/apache/helix/gateway/util/PerKeyBlockingExecutor.java
@@ -55,6 +55,8 @@ public class PerKeyBlockingExecutor {
_queueLock.lock();
try {
if (!_runningEvents.contains(key)) {
+ // Add to running events BEFORE executing to avoid race condition
+ _runningEvents.add(key);
_executor.execute(() -> runEvent(key, event));
} else {
_pendingBlockedEvents.computeIfAbsent(key, k -> new
ConcurrentLinkedQueue<>());
@@ -67,7 +69,6 @@ public class PerKeyBlockingExecutor {
private void runEvent(String key, Runnable event) {
try {
- _runningEvents.add(key);
event.run();
} finally {
_queueLock.lock();