Skip to content

Commit ecf18c0

Browse files
author
Vincent Potucek
committed
[tryout fix] concurrency bug in NamespacedHierarchicalStore#computeIfAbsent(Object, Object, Function) junit-team#5171 junit-team#5209
Signed-off-by: Vincent Potucek <vpotucek@me.com>
1 parent 41b4166 commit ecf18c0

File tree

1 file changed

+47
-49
lines changed

1 file changed

+47
-49
lines changed

platform-tests/src/test/java/org/junit/platform/engine/support/store/NamespacedHierarchicalStoreTests.java

Lines changed: 47 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -711,11 +711,57 @@ public int hashCode() {
711711
// Force all CollidingKey instances to have the same hash code
712712
return 42;
713713
}
714+
}@SuppressWarnings("deprecation")
715+
@Test
716+
void getOrComputeIfAbsentDoesNotDeadlockWithCollidingKeys() throws Exception {
717+
var store = new NamespacedHierarchicalStore<String>(null);
718+
var latch1 = new CountDownLatch(1);
719+
var latch2 = new CountDownLatch(1);
720+
721+
var thread1 = new Thread(() -> {
722+
store.getOrComputeIfAbsent("ns", new CollidingKey(1), key -> {
723+
latch1.countDown();
724+
try {
725+
// Wait for second thread to start its computation
726+
latch2.await();
727+
}
728+
catch (InterruptedException e) {
729+
Thread.currentThread().interrupt();
730+
throw new RuntimeException(e);
731+
}
732+
return "value1";
733+
});
734+
});
735+
736+
var thread2 = new Thread(() -> {
737+
try {
738+
// Wait for first thread to start its computation
739+
latch1.await();
740+
store.getOrComputeIfAbsent("ns", new CollidingKey(2), key -> {
741+
latch2.countDown();
742+
return "value2";
743+
});
744+
}
745+
catch (InterruptedException e) {
746+
Thread.currentThread().interrupt();
747+
throw new RuntimeException(e);
748+
}
749+
});
750+
751+
thread1.start();
752+
thread2.start();
753+
754+
// Wait with timeout to detect deadlocks
755+
thread1.join(5000);
756+
thread2.join(5000);
757+
758+
assertFalse(thread1.isAlive(), "Thread1 should have completed (no deadlock)");
759+
assertFalse(thread2.isAlive(), "Thread2 should have completed (no deadlock)");
714760
}
715761

716762
@SuppressWarnings("deprecation")
717763
@Test
718-
void getOrComputeIfAbsentDoesNotDeadlockWithCollidingKeys() throws Exception {
764+
void getOrComputeIfAbsentDoesNotDeadlockWithCollidingKeys2() throws Exception {
719765
try (var localStore = new NamespacedHierarchicalStore<String>(null)) {
720766
var firstComputationStarted = new CountDownLatch(1);
721767
var secondComputationAllowedToFinish = new CountDownLatch(1);
@@ -1149,54 +1195,6 @@ void computeIfAbsentWithExceptionInMemoizingSupplierPropagation() {
11491195

11501196
}
11511197

1152-
@SuppressWarnings("deprecation")
1153-
@Test
1154-
void getOrComputeIfAbsentDoesNotDeadlockWithCollidingKeys() throws Exception {
1155-
var store = new NamespacedHierarchicalStore<String>(null);
1156-
var latch1 = new CountDownLatch(1);
1157-
var latch2 = new CountDownLatch(1);
1158-
1159-
var thread1 = new Thread(() -> {
1160-
store.getOrComputeIfAbsent("ns", new CollidingKey(1), key -> {
1161-
latch1.countDown();
1162-
try {
1163-
// Wait for second thread to start its computation
1164-
latch2.await();
1165-
}
1166-
catch (InterruptedException e) {
1167-
Thread.currentThread().interrupt();
1168-
throw new RuntimeException(e);
1169-
}
1170-
return "value1";
1171-
});
1172-
});
1173-
1174-
var thread2 = new Thread(() -> {
1175-
try {
1176-
// Wait for first thread to start its computation
1177-
latch1.await();
1178-
store.getOrComputeIfAbsent("ns", new CollidingKey(2), key -> {
1179-
latch2.countDown();
1180-
return "value2";
1181-
});
1182-
}
1183-
catch (InterruptedException e) {
1184-
Thread.currentThread().interrupt();
1185-
throw new RuntimeException(e);
1186-
}
1187-
});
1188-
1189-
thread1.start();
1190-
thread2.start();
1191-
1192-
// Wait with timeout to detect deadlocks
1193-
thread1.join(5000);
1194-
thread2.join(5000);
1195-
1196-
assertFalse(thread1.isAlive(), "Thread1 should have completed (no deadlock)");
1197-
assertFalse(thread2.isAlive(), "Thread2 should have completed (no deadlock)");
1198-
}
1199-
12001198
@Test
12011199
void computeIfAbsentOverridesParentNullValue() {
12021200
var parent = new NamespacedHierarchicalStore<String>(null);

0 commit comments

Comments
 (0)