From f48f54c9f4608d5285526cba603067466bd552a8 Mon Sep 17 00:00:00 2001 From: Simeon Andreev Date: Fri, 10 Jun 2022 17:36:11 +0200 Subject: [PATCH] This change prevents an endless loop in: ReentrantCycleDetectingLock.detectPotentialLocksCycle() Due to how code in ReentrantCycleDetectingLock.lockOrDetectPotentialLocksCycle() is synchronized, its possible for a thread to both own/hold a lock (according to ReentrantCycleDetectingLock.lockOwnerThread) and wait on the same lock (according to CycleDetectingLock.lockThreadIsWaitingOn). In this state, if another thread tries to hold the same lock an endless loop will occur when calling detectPotentialLocksCycle(). With this change detectPotentialLocksCycle() removes the lock owning thread from ReentrantCycleDetectingLock.lockOwnerThread, if it detects that "this" lock is both waited on and owned by the same thread. This prevents the endless loop during cycle detection. Fix for: #1510 --- core/src/com/google/inject/internal/CycleDetectingLock.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/src/com/google/inject/internal/CycleDetectingLock.java b/core/src/com/google/inject/internal/CycleDetectingLock.java index d767015548..db91f088d9 100644 --- a/core/src/com/google/inject/internal/CycleDetectingLock.java +++ b/core/src/com/google/inject/internal/CycleDetectingLock.java @@ -259,6 +259,11 @@ private ListMultimap detectPotentialLocksCycle() { // owner thread depends on current thread, cycle detected return potentialLocksCycle; } + // Its possible the lock owner thread has not removed itself yet from the waiting-on-lock list. + // So we remove it here, to prevent an endless loop. See #1510. + if (lockOwnerWaitingOn == this) { + lockThreadIsWaitingOn.remove(this.lockOwnerThread); + } } // no dependency path from an owner thread to a current thread return ImmutableListMultimap.of();