Potential deadlock in LockManagerImpl
-------------------------------------

                 Key: JCR-2791
                 URL: https://issues.apache.org/jira/browse/JCR-2791
             Project: Jackrabbit Content Repository
          Issue Type: Bug
          Components: jackrabbit-core
            Reporter: Jukka Zitting
            Priority: Minor


I have a deadlock case that consists of the following *three* threads blocking 
each other:

Thread A - a writer that's waiting for a write lock on the SISM:

    - waiting on <0x29283ca6> (a 
EDU.oswego.cs.dl.util.concurrent.WriterPreferenceReadWriteLock$WriterLock)
    - locked <0x29283ca6> (a 
EDU.oswego.cs.dl.util.concurrent.WriterPreferenceReadWriteLock$WriterLock)
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:485)
    at 
EDU.oswego.cs.dl.util.concurrent.WriterPreferenceReadWriteLock$WriterLock.acquire(Unknown
 Source)
    at 
org.apache.jackrabbit.core.state.DefaultISMLocking$WriteLockImpl.<init>(DefaultISMLocking.java:76)
    at 
org.apache.jackrabbit.core.state.DefaultISMLocking$WriteLockImpl.<init>(DefaultISMLocking.java:70)
    at 
org.apache.jackrabbit.core.state.DefaultISMLocking.acquireWriteLock(DefaultISMLocking.java:64)
    at 
org.apache.jackrabbit.core.state.SharedItemStateManager.acquireWriteLock(SharedItemStateManager.java:1471)
    at 
org.apache.jackrabbit.core.state.SharedItemStateManager.access$200(SharedItemStateManager.java:112)
    at 
org.apache.jackrabbit.core.state.SharedItemStateManager$Update.begin(SharedItemStateManager.java:555)
    at 
org.apache.jackrabbit.core.state.SharedItemStateManager.beginUpdate(SharedItemStateManager.java:1110)
    at 
org.apache.jackrabbit.core.state.SharedItemStateManager.update(SharedItemStateManager.java:1140)
    at 
org.apache.jackrabbit.core.state.LocalItemStateManager.update(LocalItemStateManager.java:351)
    at 
org.apache.jackrabbit.core.state.XAItemStateManager.update(XAItemStateManager.java:354)
    at 
org.apache.jackrabbit.core.state.LocalItemStateManager.update(LocalItemStateManager.java:326)
    at 
org.apache.jackrabbit.core.state.SessionItemStateManager.update(SessionItemStateManager.java:328)
    at org.apache.jackrabbit.core.ItemImpl.save(ItemImpl.java:1141)

Thread B - a reader that's waiting for a read lock on the SISM:

    - waiting on <0x7d1d0717> (a 
EDU.oswego.cs.dl.util.concurrent.WriterPreferenceReadWriteLock$ReaderLock)
    - locked <0x7d1d0717> (a 
EDU.oswego.cs.dl.util.concurrent.WriterPreferenceReadWriteLock$ReaderLock)
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:485)
    at 
EDU.oswego.cs.dl.util.concurrent.WriterPreferenceReadWriteLock$ReaderLock.acquire(Unknown
 Source)
    at 
org.apache.jackrabbit.core.state.DefaultISMLocking$ReadLockImpl.<init>(DefaultISMLocking.java:102)
    at 
org.apache.jackrabbit.core.state.DefaultISMLocking$ReadLockImpl.<init>(DefaultISMLocking.java:96)
    at 
org.apache.jackrabbit.core.state.DefaultISMLocking.acquireReadLock(DefaultISMLocking.java:53)
    at 
org.apache.jackrabbit.core.state.SharedItemStateManager.acquireReadLock(SharedItemStateManager.java:1457)
    at 
org.apache.jackrabbit.core.state.SharedItemStateManager.getItemState(SharedItemStateManager.java:250)
    at 
org.apache.jackrabbit.core.state.LocalItemStateManager.getNodeState(LocalItemStateManager.java:107)
    at 
org.apache.jackrabbit.core.state.LocalItemStateManager.getItemState(LocalItemStateManager.java:172)
    at 
org.apache.jackrabbit.core.state.SessionItemStateManager.getItemState(SessionItemStateManager.java:200)
    at 
org.apache.jackrabbit.core.HierarchyManagerImpl.getItemState(HierarchyManagerImpl.java:152)
    at 
org.apache.jackrabbit.core.HierarchyManagerImpl.getPath(HierarchyManagerImpl.java:395)
    at 
org.apache.jackrabbit.core.CachingHierarchyManager.getPath(CachingHierarchyManager.java:232)
    at 
org.apache.jackrabbit.core.lock.LockManagerImpl.getPath(LockManagerImpl.java:856)
    at 
org.apache.jackrabbit.core.lock.LockManagerImpl.getLockInfo(LockManagerImpl.java:547)
    at 
org.apache.jackrabbit.core.lock.XALockManager.isLocked(XALockManager.java:158)
    at 
org.apache.jackrabbit.core.lock.SessionLockManager.isLocked(SessionLockManager.java:108)
    at org.apache.jackrabbit.core.NodeImpl.isLocked(NodeImpl.java:3325)

Thread C - a writer that's delivering synchronous observation events to a 
LockManagerImpl instance:

    - waiting on <0x3fc267ca> (a 
org.apache.jackrabbit.core.state.LocalItemStateManager)
    - locked <0x3fc267ca> (a 
org.apache.jackrabbit.core.state.LocalItemStateManager)
     owned by Thread B
    at 
org.apache.jackrabbit.core.state.LocalItemStateManager.getItemState(LocalItemStateManager.java:167)
    at 
org.apache.jackrabbit.core.state.SessionItemStateManager.getItemState(SessionItemStateManager.java:200)
    at org.apache.jackrabbit.core.ItemManager.getItemData(ItemManager.java:390)
    at org.apache.jackrabbit.core.ItemManager.getItem(ItemManager.java:336)
    at org.apache.jackrabbit.core.ItemManager.getItem(ItemManager.java:615)
    at 
org.apache.jackrabbit.core.lock.LockManagerImpl.refresh(LockManagerImpl.java:1186)
    at 
org.apache.jackrabbit.core.lock.LockManagerImpl.nodeAdded(LockManagerImpl.java:1217)
    at 
org.apache.jackrabbit.core.lock.LockManagerImpl.onEvent(LockManagerImpl.java:1120)
    at 
org.apache.jackrabbit.core.observation.EventConsumer.consumeEvents(EventConsumer.java:246)
    at 
org.apache.jackrabbit.core.observation.ObservationDispatcher.dispatchEvents(ObservationDispatcher.java:214)
    at 
org.apache.jackrabbit.core.observation.EventStateCollection.dispatch(EventStateCollection.java:475)
    at 
org.apache.jackrabbit.core.state.SharedItemStateManager$Update.end(SharedItemStateManager.java:765)
    at 
org.apache.jackrabbit.core.state.SharedItemStateManager.update(SharedItemStateManager.java:1140)
    at 
org.apache.jackrabbit.core.state.LocalItemStateManager.update(LocalItemStateManager.java:351)
    at 
org.apache.jackrabbit.core.state.XAItemStateManager.update(XAItemStateManager.java:354)
    at 
org.apache.jackrabbit.core.state.LocalItemStateManager.update(LocalItemStateManager.java:326)
    at 
org.apache.jackrabbit.core.state.SessionItemStateManager.update(SessionItemStateManager.java:328)
    at org.apache.jackrabbit.core.ItemImpl.save(ItemImpl.java:1141)

The problem here is that thread C is trying to deliver synchronous observation 
events (i.e. it's still holding a downgraded SISM lock) to the LockManagerImpl 
instance of the session used in thread B. The event handling code in 
LockManagerImpl uses the session-local LocalItemStateManager instance, whose 
monitor has already been entered by thread B. Thread B is being blocked by 
thread A and the writer preference nature of the SISM lock, and thread A can't 
proceed until thread C has released the SISM lock it's currently holding.

The specific LocalItemStateManager synchronization block seen here has already 
been removed as a part of my JCR-2699 changes, so this specific deadlock can no 
longer occur with the latest trunk, but I'm still filing this issue at "Minor" 
priority as we should still review the above scenario for other potential 
deadlock issues. Ideally we'd either make the LockManagerImpl use normal 
instead of synchronous observation, or avoid ItemManager access in the 
LockManagerImpl event processing code.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to