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.