Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
scr-2.1.16
-
None
Description
There is a possible deadlock in the ComponentRegistry and it goes like this:
The update of the change count is setting up a timer to execute a task while it is holding a lock. The task in turn, is grabbing that lock when activated and calls into the service registry while holding the lock.
Now, when a service gets unregistered that is coming from a factory - the service registry will do an upcall that triggers scr to update the change count and hence, trying to grab the lock mentioned above.
That can cause a case where the task has the lock and is waiting in the service registry which is waiting on scr, which is waiting for the lock.
E.g.:
For the tasks:
java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x00000007bc02ea40> (a java.util.concurrent.CountDownLatch$Sync) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836) at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:997) at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304) at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:231) at org.apache.felix.framework.ServiceRegistry.getService(ServiceRegistry.java:368) at org.apache.felix.framework.EventDispatcher.filterListenersUsingHooks(EventDispatcher.java:618) at org.apache.felix.framework.EventDispatcher.fireServiceEvent(EventDispatcher.java:542) at org.apache.felix.framework.Felix.fireServiceEvent(Felix.java:4833) at org.apache.felix.framework.Felix.access$000(Felix.java:112) at org.apache.felix.framework.Felix$1.serviceChanged(Felix.java:434) at org.apache.felix.framework.ServiceRegistry.servicePropertiesModified(ServiceRegistry.java:612) at org.apache.felix.framework.ServiceRegistrationImpl.setProperties(ServiceRegistrationImpl.java:132) at org.apache.felix.scr.impl.ComponentRegistry$4.run(ComponentRegistry.java:743) - locked <0x000000074376fb00> (a java.lang.Object) at java.util.TimerThread.mainLoop(Timer.java:555) at java.util.TimerThread.run(Timer.java:505)
and for the update:
java.lang.Thread.State: BLOCKED (on object monitor) at org.apache.felix.scr.impl.ComponentRegistry.updateChangeCount(ComponentRegistry.java:722) - waiting to lock <0x000000074376fb00> (a java.lang.Object) at org.apache.felix.scr.impl.BundleComponentActivator.updateChangeCount(BundleComponentActivator.java:778) at org.apache.felix.scr.impl.manager.AbstractComponentManager.setState(AbstractComponentManager.java:1420) at org.apache.felix.scr.impl.manager.SingleComponentManager.getServiceInternal(SingleComponentManager.java:962) at org.apache.felix.scr.impl.manager.SingleComponentManager.getService(SingleComponentManager.java:900) at org.apache.felix.framework.ServiceRegistrationImpl.getFactoryUnchecked(ServiceRegistrationImpl.java:348) at org.apache.felix.framework.ServiceRegistrationImpl.getService(ServiceRegistrationImpl.java:248) at org.apache.felix.framework.ServiceRegistry.getService(ServiceRegistry.java:350) at org.apache.felix.framework.EventDispatcher.filterListenersUsingHooks(EventDispatcher.java:618) at org.apache.felix.framework.EventDispatcher.fireServiceEvent(EventDispatcher.java:542) at org.apache.felix.framework.Felix.fireServiceEvent(Felix.java:4833) at org.apache.felix.framework.Felix.access$000(Felix.java:112) at org.apache.felix.framework.Felix$1.serviceChanged(Felix.java:434) at org.apache.felix.framework.ServiceRegistry.unregisterService(ServiceRegistry.java:170)
cziegeler, could you have a look and see if that is fixable by not holding the lock while calling into the serviceregistry?