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, before chekcing for lock cycles.
This prevents the endless loop during cycle detection.

Fix for: google#1510
  • Loading branch information
trancexpress committed Jun 10, 2022
1 parent c7a74a1 commit 4e9022a
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 4e9022a

Please sign in to comment.