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().

The change adds a workaround, forcing the cycle detection to exit if the above condition is met.

Workaround for: #1510
  • Loading branch information
trancexpress committed Jun 10, 2022
1 parent c7a74a1 commit 2f46a53
Showing 1 changed file with 3 additions and 0 deletions.
3 changes: 3 additions & 0 deletions core/src/com/google/inject/internal/CycleDetectingLock.java
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,9 @@ private ListMultimap<Thread, ID> detectPotentialLocksCycle() {
MultimapBuilder.linkedHashKeys().arrayListValues().build();
// lock that is a part of a potential locks cycle, starts with current lock
ReentrantCycleDetectingLock<?> lockOwnerWaitingOn = this;
// 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.
lockThreadIsWaitingOn.remove(lockOwnerWaitingOn.lockOwnerThread);
// try to find a dependency path between lock's owner thread and a current thread
while (lockOwnerWaitingOn != null && lockOwnerWaitingOn.lockOwnerThread != null) {
Thread threadOwnerThreadWaits = lockOwnerWaitingOn.lockOwnerThread;
Expand Down

0 comments on commit 2f46a53

Please sign in to comment.