jackrabbit-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Stephan Huttenhuis (JIRA)" <j...@apache.org>
Subject [jira] Updated: (JCR-2525) NodeState and NodeStateListener deadlock
Date Fri, 02 Apr 2010 07:36:27 GMT

     [ https://issues.apache.org/jira/browse/JCR-2525?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]

Stephan Huttenhuis updated JCR-2525:
------------------------------------

    Status: Patch Available  (was: Open)

Concerning your patches. The JCR_Deadlock_changes.diff introduces a cacheMonitor lock for
all methods related to the childNodeEntries object. Then JCR_Deadlock_additionalChanges.txt
uses the NodeState monitor lock for get methods. This creates 2 different locks for the invariant
on childNodeEntries and this is incorrect. I took the liberty to rewrite the test class to
a junit test (see ItemStateHierarchyManagerDeadlockTest.java).

I have a different proposed solution. A concurrency design rule is to never give control to
a client within a synchronized block. This means that you must not call methods of which the
class has no knowledge of what the method does and has no control over it (alien methods).
In this case calling the listener is such a situation in NodeState. A solution is to remove
the listener 

notification calls from the synchronized block and to limit the synchronized block to the
operations on the childNodeEntries object. 

Outside the lock a ChildNodeEntry is passed to the listener, but ChildNodeEntry is immutable
and therefore thread-safe. Also the NodeState is passed to the listener. If the listener calls
a method on the NodeState the monitor lock is aquired again if needed. See JCR-2525-listener-outside-lock.patch
(based on the 1.6 branch).

> NodeState and NodeStateListener deadlock
> ----------------------------------------
>
>                 Key: JCR-2525
>                 URL: https://issues.apache.org/jira/browse/JCR-2525
>             Project: Jackrabbit Content Repository
>          Issue Type: Bug
>          Components: jackrabbit-core
>    Affects Versions: 1.6.1, 1.6.0
>            Reporter: Frederic Guilbeault
>            Priority: Critical
>         Attachments: ItemStateHierarchyManagerDeadlockTest.java, JCR-2525-listener-outside-lock.patch,
JCR_Deadlock_additionalChanges.txt, JCR_Deadlock_changes.diff, JCRDeadlockTest.zip, threads_stuck.txt
>
>
> Java stack information for the threads listed above:
> ===================================================
> "jmssecondaryApplnJobExecutor-8":
> 	at org.apache.jackrabbit.core.state.NodeState.getChildNodeEntry(NodeState.java:300)
> 	- waiting to lock <0x9e6c6d08> (a org.apache.jackrabbit.core.state.NodeState)
> 	at org.apache.jackrabbit.core.CachingHierarchyManager.nodeModified(CachingHierarchyManager.java:316)
> 	- locked <0xa09882a8> (a java.lang.Object)
> 	at org.apache.jackrabbit.core.CachingHierarchyManager.stateModified(CachingHierarchyManager.java:293)
> 	at org.apache.jackrabbit.core.state.StateChangeDispatcher.notifyStateModified(StateChangeDispatcher.java:111)
> 	at org.apache.jackrabbit.core.state.SessionItemStateManager.stateModified(SessionItemStateManager.java:889)
> 	at org.apache.jackrabbit.core.state.StateChangeDispatcher.notifyStateModified(StateChangeDispatcher.java:111)
> 	at org.apache.jackrabbit.core.state.LocalItemStateManager.stateModified(LocalItemStateManager.java:452)
> 	at org.apache.jackrabbit.core.state.XAItemStateManager.stateModified(XAItemStateManager.java:602)
> 	at org.apache.jackrabbit.core.state.StateChangeDispatcher.notifyStateModified(StateChangeDispatcher.java:111)
> 	at org.apache.jackrabbit.core.state.SharedItemStateManager.stateModified(SharedItemStateManager.java:400)
> 	at org.apache.jackrabbit.core.state.ItemState.notifyStateUpdated(ItemState.java:244)
> 	at org.apache.jackrabbit.core.state.ChangeLog.persisted(ChangeLog.java:297)
> 	at org.apache.jackrabbit.core.state.SharedItemStateManager$Update.end(SharedItemStateManager.java:749)
> 	at org.apache.jackrabbit.core.state.SharedItemStateManager.update(SharedItemStateManager.java:1115)
> 	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:325)
> 	at org.apache.jackrabbit.core.ItemImpl.save(ItemImpl.java:1111)
> 	- locked <0x9b1b0be0> (a org.apache.jackrabbit.core.XASessionImpl)
> 	at org.apache.jackrabbit.core.SessionImpl.save(SessionImpl.java:915)
> 	at org.apache.jackrabbit.jca.JCASessionHandle.save(JCASessionHandle.java:180)
>         ...
> 	at sun.reflect.GeneratedMethodAccessor1067.invoke(Unknown Source)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> 	at java.lang.reflect.Method.invoke(Method.java:597)
> 	at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:36)
> 	at sun.reflect.GeneratedMethodAccessor110.invoke(Unknown Source)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> 	at java.lang.reflect.Method.invoke(Method.java:597)
> 	at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:243)
> 	at javax.management.modelmbean.RequiredModelMBean.invokeMethod(RequiredModelMBean.java:1074)
> 	at javax.management.modelmbean.RequiredModelMBean.invoke(RequiredModelMBean.java:955)
> 	at org.springframework.jmx.export.SpringModelMBean.invoke(SpringModelMBean.java:88)
> 	at org.jboss.mx.server.RawDynamicInvoker.invoke(RawDynamicInvoker.java:164)
> 	at org.jboss.mx.modelmbean.RequiredModelMBeanInvoker.invoke(RequiredModelMBeanInvoker.java:127)
> 	at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
> 	at org.jboss.system.server.jmx.LazyMBeanServer.invoke(LazyMBeanServer.java:291)
> 	at javax.management.MBeanServerInvocationHandler.invoke(MBeanServerInvocationHandler.java:288)
> 	at $Proxy692.doDiscoveryNow(Unknown Source)
>         ...
> 	at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:531)
> 	at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:466)
> 	at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:435)
> 	at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:322)
> 	at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:260)
> 	at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:944)
> 	at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:868)
> 	at java.lang.Thread.run(Thread.java:619)
> "jmssecondaryApplnJobExecutor-7":
> 	at org.apache.jackrabbit.core.CachingHierarchyManager.nodeAdded(CachingHierarchyManager.java:362)
> 	- waiting to lock <0xa09882a8> (a java.lang.Object)
> 	at org.apache.jackrabbit.core.state.StateChangeDispatcher.notifyNodeAdded(StateChangeDispatcher.java:159)
> 	at org.apache.jackrabbit.core.state.SessionItemStateManager.nodeAdded(SessionItemStateManager.java:947)
> 	at org.apache.jackrabbit.core.state.NodeState.notifyNodeAdded(NodeState.java:882)
> 	at org.apache.jackrabbit.core.state.NodeState.addChildNodeEntry(NodeState.java:351)
> 	- locked <0x9e6c6d08> (a org.apache.jackrabbit.core.state.NodeState)
> 	at org.apache.jackrabbit.core.NodeImpl.createChildNode(NodeImpl.java:541)
> 	- locked <0xa00619a8> (a org.apache.jackrabbit.core.NodeImpl)
> 	at org.apache.jackrabbit.core.NodeImpl.internalAddChildNode(NodeImpl.java:802)
> 	at org.apache.jackrabbit.core.NodeImpl.internalAddNode(NodeImpl.java:735)
> 	at org.apache.jackrabbit.core.NodeImpl.addNodeWithUuid(NodeImpl.java:2200)
> 	- locked <0xa00619f8> (a org.apache.jackrabbit.core.NodeImpl)
> 	at org.apache.jackrabbit.core.NodeImpl.addNode(NodeImpl.java:2133)
> 	- locked <0xa00619f8> (a org.apache.jackrabbit.core.NodeImpl)
>         ...
> 	at sun.reflect.GeneratedMethodAccessor1067.invoke(Unknown Source)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> 	at java.lang.reflect.Method.invoke(Method.java:597)
> 	at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:36)
> 	at sun.reflect.GeneratedMethodAccessor110.invoke(Unknown Source)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> 	at java.lang.reflect.Method.invoke(Method.java:597)
> 	at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:243)
> 	at javax.management.modelmbean.RequiredModelMBean.invokeMethod(RequiredModelMBean.java:1074)
> 	at javax.management.modelmbean.RequiredModelMBean.invoke(RequiredModelMBean.java:955)
> 	at org.springframework.jmx.export.SpringModelMBean.invoke(SpringModelMBean.java:88)
> 	at org.jboss.mx.server.RawDynamicInvoker.invoke(RawDynamicInvoker.java:164)
> 	at org.jboss.mx.modelmbean.RequiredModelMBeanInvoker.invoke(RequiredModelMBeanInvoker.java:127)
> 	at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
> 	at org.jboss.system.server.jmx.LazyMBeanServer.invoke(LazyMBeanServer.java:291)
> 	at javax.management.MBeanServerInvocationHandler.invoke(MBeanServerInvocationHandler.java:288)
> 	at $Proxy692.doDiscoveryNow(Unknown Source)
>         ...
> 	at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:531)
> 	at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:466)
> 	at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:435)
> 	at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:322)
> 	at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:260)
> 	at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:944)
> 	at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:868)
> 	at java.lang.Thread.run(Thread.java:619)
> Found 1 deadlock.

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


Mime
View raw message