From 431d551182b4ab410479d0208a5c6ac8d6120f37 Mon Sep 17 00:00:00 2001 From: Elliotte Rusty Harold Date: Tue, 4 Aug 2026 18:32:53 +0000 Subject: [PATCH 1/2] Fix deadlock in IPC named lock access tests The shared/exclusive/mixed access tests in NamedLockFactoryTestSupport deadlock when both competing threads fail to acquire the lock within the 100 ms acquisition timeout (e.g. the IPC server thread being starved on a loaded CI machine): both threads count down the loser latch and then block forever on winner.await(), so the winners latch is never released and the test hangs until @Timeout fires. Fix by giving the lock acquisition a 1 s timeout (the loser still fails while the winner holds, so mutual exclusion is still verified) and by bounding the winner/loser handshake and the test-side joins/awaits so the test fails fast with a clear message instead of hanging. Closes #2030 --- .../ipc/NamedLockFactoryTestSupport.java | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/maven-resolver-named-locks-ipc/src/test/java/org/eclipse/aether/named/ipc/NamedLockFactoryTestSupport.java b/maven-resolver-named-locks-ipc/src/test/java/org/eclipse/aether/named/ipc/NamedLockFactoryTestSupport.java index c9abc4417f..dab659d376 100644 --- a/maven-resolver-named-locks-ipc/src/test/java/org/eclipse/aether/named/ipc/NamedLockFactoryTestSupport.java +++ b/maven-resolver-named-locks-ipc/src/test/java/org/eclipse/aether/named/ipc/NamedLockFactoryTestSupport.java @@ -131,10 +131,10 @@ public void sharedAccess(TestInfo testInfo) throws InterruptedException { Thread t2 = new Thread(new Access(namedLockFactory, keys, true, winners, losers)); t1.start(); t2.start(); - t1.join(); - t2.join(); - winners.await(); - losers.await(); + t1.join(5000); + t2.join(5000); + assertTrue(winners.await(5, TimeUnit.SECONDS), "expected both threads to win"); + assertTrue(losers.await(5, TimeUnit.SECONDS), "expected no loser"); } @Test @@ -147,10 +147,10 @@ public void exclusiveAccess(TestInfo testInfo) throws InterruptedException { Thread t2 = new Thread(new Access(namedLockFactory, keys, false, winners, losers)); t1.start(); t2.start(); - t1.join(); - t2.join(); - winners.await(); - losers.await(); + t1.join(5000); + t2.join(5000); + assertTrue(winners.await(5, TimeUnit.SECONDS), "expected a winner"); + assertTrue(losers.await(5, TimeUnit.SECONDS), "expected a loser"); } @Test @@ -163,10 +163,10 @@ public void mixedAccess(TestInfo testInfo) throws InterruptedException { Thread t2 = new Thread(new Access(namedLockFactory, keys, false, winners, losers)); t1.start(); t2.start(); - t1.join(); - t2.join(); - winners.await(); - losers.await(); + t1.join(5000); + t2.join(5000); + assertTrue(winners.await(5, TimeUnit.SECONDS), "expected a winner"); + assertTrue(losers.await(5, TimeUnit.SECONDS), "expected a loser"); } private static class Access implements Runnable { @@ -193,17 +193,17 @@ public Access( public void run() { try (NamedLock lock = namedLockFactory.getLock(keys)) { if (shared - ? lock.lockShared(100L, TimeUnit.MILLISECONDS) - : lock.lockExclusively(100L, TimeUnit.MILLISECONDS)) { + ? lock.lockShared(1000L, TimeUnit.MILLISECONDS) + : lock.lockExclusively(1000L, TimeUnit.MILLISECONDS)) { try { winner.countDown(); - loser.await(); + loser.await(5, TimeUnit.SECONDS); } finally { lock.unlock(); } } else { loser.countDown(); - winner.await(); + winner.await(5, TimeUnit.SECONDS); } } catch (InterruptedException e) { fail(e.getMessage()); From bdd0984cf6caf0e839cc26ea295f49b0ea5d6543 Mon Sep 17 00:00:00 2001 From: Elliotte Rusty Harold Date: Tue, 4 Aug 2026 15:29:26 -0400 Subject: [PATCH 2/2] retrigger checks