public class LockGate
extends Object
This class creates a first-come, first-serve local queue for locks.
The usage model is as follows:
(1) There is one lock gate per key for all threads.
(2) The LockGate replaces LockObjects in the pool, but each LockGate refers to
a LockObject. They are separate objects though because they require separate locking.
(3) When a lock is desired, the appropriate LockGate method is called to obtain
the lock. This method places the thread ID onto the queue, and waits until
the thread ID reaches the head of the queue before executing the lock request.
(4) Only when the lock request is successful, or is aborted, is the thread ID
removed from the queue. Write requests therefore serve to block read requests
until the write request is serviced.
Preferred structure:
try {
... obtain the lock ...
} finally {
}
Seeing lockups. These lockups are characterized by a thread waiting on a lock object
while another thread waits on permission to do something else with the lock object.
It is by no means clear at this point how this situation causes a hang-up; the
lock object is waiting to be awakened, but there is no obvious entity holding the lock elsewhere.
But one thread (A) seems always to be in a multi-lock situation, waiting to obtain a lock, e.g.:
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:503)
at org.apache.manifoldcf.core.lockmanager.LockObject.enterWriteLock(LockObject.java:80)
- locked <0x00000000fe205720> (a org.apache.manifoldcf.core.lockmanager.LockObject)
at org.apache.manifoldcf.core.lockmanager.LockGate.enterWriteLock(LockGate.java:132)
at org.apache.manifoldcf.core.lockmanager.BaseLockManager.enter(BaseLockManager.java:1483)
at org.apache.manifoldcf.core.lockmanager.BaseLockManager.enterCriticalSections(BaseLockManager.java:920)
at org.apache.manifoldcf.core.lockmanager.LockManager.enterCriticalSections(LockManager.java:455)
Here's the second thread (B), which is waitingForPermission:
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000f8b71c78> (a org.apache.manifoldcf.core.lockmanager.LockGate)
at java.lang.Object.wait(Object.java:503)
at org.apache.manifoldcf.core.lockmanager.LockGate.waitForPermission(LockGate.java:91)
- locked <0x00000000f8b71c78> (a org.apache.manifoldcf.core.lockmanager.LockGate)
at org.apache.manifoldcf.core.lockmanager.LockGate.enterWriteLock(LockGate.java:129)
at org.apache.manifoldcf.core.lockmanager.BaseLockManager.enterWrite(BaseLockManager.java:1130)
at org.apache.manifoldcf.core.lockmanager.BaseLockManager.enterWriteCriticalSection(BaseLockManager.java:896)
at org.apache.manifoldcf.core.lockmanager.LockManager.enterWriteCriticalSection(LockManager.java:431)
at org.apache.manifoldcf.core.interfaces.IDFactory.make(IDFactory.java:55)
The problem is that (A) has already obtained permission, but cannot obtain the lock. (B) is somehow blocking
(A) from obtaining the lock even though it has not yet taken its own lock! Or, maybe it has, and we don't see it in
the stack trace.
Another example: (C)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000ffbdc038> (a org.apache.manifoldcf.core.lockmanager.LockGate)
at java.lang.Object.wait(Object.java:503)
at org.apache.manifoldcf.core.lockmanager.LockGate.waitForPermission(LockGate.java:91)
- locked <0x00000000ffbdc038> (a org.apache.manifoldcf.core.lockmanager.LockGate)
at org.apache.manifoldcf.core.lockmanager.LockGate.enterReadLock(LockGate.java:211)
at org.apache.manifoldcf.core.lockmanager.BaseLockManager.enter(BaseLockManager.java:1532)
at org.apache.manifoldcf.core.lockmanager.BaseLockManager.enterLocks(BaseLockManager.java:813)
at org.apache.manifoldcf.core.lockmanager.LockManager.enterLocks(LockManager.java:355)
and (D):
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000ffbdd2f8> (a org.apache.manifoldcf.core.lockmanager.LockObject)
at java.lang.Object.wait(Object.java:503)
at org.apache.manifoldcf.core.lockmanager.LockObject.enterWriteLock(LockObject.java:83)
- locked <0x00000000ffbdd2f8> (a org.apache.manifoldcf.core.lockmanager.LockObject)
at org.apache.manifoldcf.core.lockmanager.LockGate.enterWriteLock(LockGate.java:132)
at org.apache.manifoldcf.core.lockmanager.BaseLockManager.enter(BaseLockManager.java:1483)
at org.apache.manifoldcf.core.lockmanager.BaseLockManager.enterLocks(BaseLockManager.java:813)
at org.apache.manifoldcf.core.lockmanager.LockManager.enterLocks(LockManager.java:355)
Problem here: The LockGate 0x00000000ffbdc038 has no other instance anywhere, which should not be able to happen.
Debugging must entail dumping ALL outstanding locks periodically -- and who holds each.