From e136b95a8070224a782debd55becb57f8f226161 Mon Sep 17 00:00:00 2001 From: Marc Philipp Date: Tue, 17 Sep 2024 14:46:33 +0200 Subject: [PATCH] Ensure nesting is only decremented when lock was acquired successfully When running Spock's tests with the latest snapshot, `pop()` seems to have been called without a prior call to `push()` on the `Deque` of resource locks. (cherry picked from commit 73c8ca2f062988bad7f56b5193ba3624f3df7b80) --- ...inPoolHierarchicalTestExecutorService.java | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/ForkJoinPoolHierarchicalTestExecutorService.java b/junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/ForkJoinPoolHierarchicalTestExecutorService.java index 9b5d2efea14c..4b2e332fd07a 100644 --- a/junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/ForkJoinPoolHierarchicalTestExecutorService.java +++ b/junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/ForkJoinPoolHierarchicalTestExecutorService.java @@ -253,17 +253,17 @@ public boolean exec() { // this means that .join() will wait. return false; } - try (ResourceLock lock = resourceLock.acquire()) { - threadLock.incrementNesting(lock); + try ( // + ResourceLock lock = resourceLock.acquire(); // + @SuppressWarnings("unused") + ThreadLock.NestedResourceLock nested = threadLock.withNesting(lock) // + ) { testTask.execute(); return true; } catch (InterruptedException e) { throw ExceptionUtils.throwAsUncheckedException(e); } - finally { - threadLock.decrementNesting(); - } } @Override @@ -300,18 +300,19 @@ void addDeferredTask(ExclusiveTask task) { deferredTasks.add(task); } - void incrementNesting(ResourceLock lock) { + NestedResourceLock withNesting(ResourceLock lock) { locks.push(lock); - } - - @SuppressWarnings("resource") - void decrementNesting() { - locks.pop(); + return locks::pop; } boolean areAllHeldLocksCompatibleWith(ResourceLock lock) { return locks.stream().allMatch(l -> l.isCompatible(lock)); } + + interface NestedResourceLock extends AutoCloseable { + @Override + void close(); + } } interface TaskEventListener {