You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by el...@apache.org on 2026/08/04 18:33:05 UTC

(maven-resolver) 01/01: Fix deadlock in IPC named lock access tests

This is an automated email from the ASF dual-hosted git repository.

elharo pushed a commit to branch fix/ipc-flaky-test-deadlock
in repository https://gitbox.apache.org/repos/asf/maven-resolver.git

commit 431d551182b4ab410479d0208a5c6ac8d6120f37
Author: Elliotte Rusty Harold <el...@ibiblio.org>
AuthorDate: Tue Aug 4 18:32:53 2026 +0000

    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
---
 .../named/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 c9abc4417..dab659d37 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 abstract class NamedLockFactoryTestSupport {
         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 abstract class NamedLockFactoryTestSupport {
         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 abstract class NamedLockFactoryTestSupport {
         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 abstract class NamedLockFactoryTestSupport {
         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());