Skip to content

Commit

Permalink
Prevent endless loop in lock cycle detection #1510
Browse files Browse the repository at this point in the history
This change prevents an endless loop in:
ReentrantCycleDetectingLock.addAllLockIdsAfter()

For reasons that are not yet clear, according to
CycleDetectingLockFactory.locksOwnedByThread and
ReentrantCycleDetectingLock.lockOwnerThread, a thread both owns a lock
and waits on that same lock. This leads to an endless loop in the cycle
detection.

The change adds a workaround, forcing the cycle detection to exit if the
above condition is met.
  • Loading branch information
trancexpress committed Jun 10, 2022
1 parent c7a74a1 commit a25812b
Showing 1 changed file with 5 additions and 0 deletions.
5 changes: 5 additions & 0 deletions core/src/com/google/inject/internal/CycleDetectingLock.java
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ private ListMultimap<Thread, ID> detectPotentialLocksCycle() {
// in case locks cycle exists lock we're waiting for is part of it
lockOwnerWaitingOn =
addAllLockIdsAfter(threadOwnerThreadWaits, lockOwnerWaitingOn, potentialLocksCycle);

if (threadOwnerThreadWaits == currentThread) {
// owner thread depends on current thread, cycle detected
return potentialLocksCycle;
Expand Down Expand Up @@ -293,6 +294,10 @@ private ReentrantCycleDetectingLock<?> addAllLockIdsAfter(
Preconditions.checkState(
found, "Internal error: We can not find locks that created a cycle that we detected");
ReentrantCycleDetectingLock<?> unownedLock = lockThreadIsWaitingOn.get(thread);
if (unownedLock == lock) {
// XXX: bandaid, how do we have a thread that owns a lock but also waits on that same lock?
return null;
}
// If this thread is waiting for a lock add it to the cycle and return it
if (unownedLock != null && unownedLock.lockFactory == this.lockFactory) {
@SuppressWarnings("unchecked")
Expand Down

0 comments on commit a25812b

Please sign in to comment.