Skip to content

Commit

Permalink
This change prevents an endless loop in: ReentrantCycleDetectingLock.…
Browse files Browse the repository at this point in the history
…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: google#1510
  • Loading branch information
trancexpress committed Jun 11, 2022
1 parent c7a74a1 commit f48f54c
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 @@ -259,6 +259,11 @@ private ListMultimap<Thread, ID> 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();
Expand Down

0 comments on commit f48f54c

Please sign in to comment.