FELIX-3456 track all locking activity to try to understand IllegalMonitorStateException on lock release
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1377081 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/config/ImmediateComponentHolder.java b/scr/src/main/java/org/apache/felix/scr/impl/config/ImmediateComponentHolder.java
index 130fd31..7ee9e69 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/config/ImmediateComponentHolder.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/config/ImmediateComponentHolder.java
@@ -188,7 +188,7 @@
if ( pid.equals( getComponentMetadata().getConfigurationPid() ) )
{
// singleton configuration deleted
- final boolean release = m_singleComponent.obtainReadLock();
+ final boolean release = m_singleComponent.obtainReadLock( "ImmediateComponentHolder.configurationDeleted.1" );
try
{
m_singleComponent.reconfigure( null );
@@ -197,7 +197,7 @@
{
if ( release )
{
- m_singleComponent.releaseReadLock();
+ m_singleComponent.releaseReadLock( "ImmediateComponentHolder.configurationDeleted.1" );
}
}
}
@@ -208,7 +208,7 @@
if ( icm != null )
{
boolean dispose = true;
- final boolean release = icm.obtainReadLock();
+ final boolean release = icm.obtainReadLock( "ImmediateComponentHolder.configurationDeleted.2" );
try
{
// special casing if the single component is deconfigured
@@ -247,7 +247,7 @@
{
if ( release )
{
- icm.releaseReadLock();
+ icm.releaseReadLock( "ImmediateComponentHolder.configurationDeleted.2" );
}
}
}
@@ -277,7 +277,7 @@
if ( pid.equals( getComponentMetadata().getConfigurationPid() ) )
{
- final boolean release = m_singleComponent.obtainReadLock();
+ final boolean release = m_singleComponent.obtainReadLock( "ImmediateComponentHolder.configurationUpdated.1" );
try
{
// singleton configuration has pid equal to component name
@@ -287,7 +287,7 @@
{
if ( release )
{
- m_singleComponent.releaseReadLock();
+ m_singleComponent.releaseReadLock( "ImmediateComponentHolder.configurationUpdated.1" );
}
}
}
@@ -297,7 +297,7 @@
final ImmediateComponentManager icm = getComponentManager( pid );
if ( icm != null )
{
- final boolean release = icm.obtainReadLock();
+ final boolean release = icm.obtainReadLock( "ImmediateComponentHolder.configurationUpdated.2" );
try
{
// factory configuration updated for existing component instance
@@ -307,7 +307,7 @@
{
if ( release )
{
- icm.releaseReadLock();
+ icm.releaseReadLock( "ImmediateComponentHolder.configurationUpdated.2" );
}
}
}
@@ -327,7 +327,7 @@
}
// configure the component
- final boolean release = newIcm.obtainReadLock();
+ final boolean release = newIcm.obtainReadLock( "ImmediateComponentHolder.configurationUpdated.3" );
try
{
newIcm.reconfigure( props );
@@ -336,7 +336,7 @@
{
if ( release )
{
- newIcm.releaseReadLock();
+ newIcm.releaseReadLock( "ImmediateComponentHolder.configurationUpdated.3" );
}
}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
index 9445777..29d8493 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
@@ -101,6 +101,7 @@
private Thread lockingThread;
private Throwable lockingStackTrace;
+ private ArrayList lockingActivity = new ArrayList( );
/**
* The constructor receives both the activator and the metadata
@@ -157,8 +158,9 @@
}
//ImmediateComponentHolder should be in this manager package and this should be default access.
- public final boolean obtainReadLock()
+ public final boolean obtainReadLock( String source )
{
+ lockingActivity.add( "obtainReadLock from: " + source + " readLocks: " + m_stateLock.getReadHoldCount() + " writeLocks: " + m_stateLock.getWriteHoldCount() + " thread: " + Thread.currentThread() + " time: " + System.currentTimeMillis());
if (m_stateLock.getReadHoldCount() >0)
{
return false;
@@ -187,13 +189,28 @@
}
- public final void releaseReadLock()
+ public final void releaseReadLock( String source )
{
- m_stateLock.unlockReadLock();
+ lockingActivity.add( "releaseReadLock from: " + source + " readLocks: " + m_stateLock.getReadHoldCount() + " writeLocks: " + m_stateLock.getWriteHoldCount() + " thread: " + Thread.currentThread() + " time: " + System.currentTimeMillis());
+ try
+ {
+ m_stateLock.unlockReadLock();
+ }
+ catch ( IllegalMonitorStateException e )
+ {
+ StringBuffer b = new StringBuffer( "Locking activity before IllegalMonitorStateException: \n" );
+ for (Iterator i = lockingActivity.iterator(); i.hasNext();)
+ {
+ b.append( " " ).append( i.next() ).append( "\n" );
+ }
+ log( LogService.LOG_ERROR, b.toString(), null );
+ throw e;
+ }
}
- final void escalateLock()
+ final void escalateLock( String source )
{
+ lockingActivity.add( "escalateLock from: " + source + " readLocks: " + m_stateLock.getReadHoldCount() + " writeLocks: " + m_stateLock.getWriteHoldCount() + " thread: " + Thread.currentThread() + " time: " + System.currentTimeMillis());
m_stateLock.unlockReadLock();
try
{
@@ -211,8 +228,9 @@
}
}
- final void deescalateLock()
+ final void deescalateLock( String source )
{
+ lockingActivity.add( "deescalateLock from: " + source + " readLocks: " + m_stateLock.getReadHoldCount() + " writeLocks: " + m_stateLock.getWriteHoldCount() + " thread: " + Thread.currentThread() + " time: " + System.currentTimeMillis());
m_stateLock.deescalate();
lockingThread = null;
lockingStackTrace = null;
@@ -240,7 +258,7 @@
{
b.append( infos[i] ).append( "\n\n" );
}
- log( LogService.LOG_INFO, b.toString(), null );
+ log( LogService.LOG_ERROR, b.toString(), null );
}
//---------- Component ID management
@@ -289,7 +307,7 @@
public final void enable( final boolean async )
{
- final boolean release = obtainReadLock();
+ final boolean release = obtainReadLock( "AbstractComponentManager.enable.1" );
try
{
enableInternal();
@@ -302,7 +320,7 @@
{
if ( release )
{
- releaseReadLock();
+ releaseReadLock( "AbstractComponentManager.enable.1" );
}
}
@@ -312,7 +330,7 @@
{
public void run()
{
- final boolean release = obtainReadLock();
+ final boolean release = obtainReadLock( "AbstractComponentManager.enable.2" );
try
{
activateInternal();
@@ -321,7 +339,7 @@
{
if ( release )
{
- releaseReadLock();
+ releaseReadLock( "AbstractComponentManager.enable.2" );
}
}
}
@@ -343,7 +361,7 @@
public final void disable( final boolean async )
{
- final boolean release = obtainReadLock();
+ final boolean release = obtainReadLock( "AbstractComponentManager.disable.1" );
try
{
if ( !async )
@@ -356,7 +374,7 @@
{
if ( release )
{
- releaseReadLock();
+ releaseReadLock( "AbstractComponentManager.disable.1" );
}
}
@@ -366,7 +384,7 @@
{
public void run()
{
- final boolean release = obtainReadLock();
+ final boolean release = obtainReadLock( "AbstractComponentManager.disable.2" );
try
{
deactivateInternal( ComponentConstants.DEACTIVATION_REASON_DISABLED );
@@ -375,7 +393,7 @@
{
if ( release )
{
- releaseReadLock();
+ releaseReadLock( "AbstractComponentManager.disable.2" );
}
}
}
@@ -407,7 +425,7 @@
*/
public void dispose( int reason )
{
- final boolean release = obtainReadLock();
+ final boolean release = obtainReadLock( "AbstractComponentManager.dispose.1" );
try
{
disposeInternal( reason );
@@ -416,7 +434,7 @@
{
if ( release )
{
- releaseReadLock();
+ releaseReadLock( "AbstractComponentManager.dispose.1" );
}
}
}
@@ -1168,7 +1186,7 @@
try
{
acm.unregisterComponentService();
- acm.escalateLock();
+ acm.escalateLock( "AbstractComponentManager.State.doDeactivate.1" );
try
{
acm.deleteComponent( reason );
@@ -1176,7 +1194,7 @@
}
finally
{
- acm.deescalateLock();
+ acm.deescalateLock( "AbstractComponentManager.State.doDeactivate.1" );
}
}
catch ( Throwable t )
@@ -1328,7 +1346,7 @@
// 4. Call the activate method, if present
if ( ( acm.isImmediate() || acm.getComponentMetadata().isFactory() ) )
{
- acm.escalateLock();
+ acm.escalateLock( "AbstractComponentManager.Unsatisifed.activate.1" );
try
{
if ( acm.isImmediate() )
@@ -1344,7 +1362,7 @@
}
finally
{
- acm.deescalateLock();
+ acm.deescalateLock( "AbstractComponentManager.Unsatisifed.activate.1" );
}
}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
index cb21db5..86713b8 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
@@ -32,7 +32,6 @@
import org.apache.felix.scr.impl.metadata.ComponentMetadata;
import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.ComponentConstants;
import org.osgi.service.component.ComponentException;
import org.osgi.service.component.ComponentFactory;
@@ -94,7 +93,7 @@
final ImmediateComponentManager cm = createComponentManager();
ComponentInstance instance;
- final boolean release = cm.obtainReadLock();
+ final boolean release = cm.obtainReadLock( "ComponentFactoryImpl.newInstance.1" );
try
{
cm.setFactoryProperties( dictionary );
@@ -116,7 +115,7 @@
{
if ( release )
{
- cm.releaseReadLock();
+ cm.releaseReadLock( "ComponentFactoryImpl.newInstance.1" );
}
}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ConfigurationComponentFactoryImpl.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ConfigurationComponentFactoryImpl.java
index a6ac519..60d5f8d 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ConfigurationComponentFactoryImpl.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ConfigurationComponentFactoryImpl.java
@@ -139,7 +139,7 @@
}
else //non-spec backwards compatible
{
- final boolean release = obtainReadLock();
+ final boolean release = obtainReadLock( "ConfigurationComponentFactoryImpl.newInstance.1" );
try
{
ImmediateComponentManager cm;
@@ -178,7 +178,7 @@
{
// update the configuration as if called as ManagedService
//TODO deadlock potential, we are holding our own state lock.
- final boolean releaseInner = cm.obtainReadLock();
+ final boolean releaseInner = cm.obtainReadLock( "ConfigurationComponentFactoryImpl.newInstance.2" );
try
{
cm.reconfigure( configuration );
@@ -187,7 +187,7 @@
{
if ( releaseInner )
{
- cm.releaseReadLock();
+ cm.releaseReadLock( "ConfigurationComponentFactoryImpl.newInstance.2" );
}
}
}
@@ -196,7 +196,7 @@
{
if ( release )
{
- releaseReadLock();
+ releaseReadLock( "ConfigurationComponentFactoryImpl.newInstance.1" );
}
}
}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
index c292180..3943fbe 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
@@ -154,7 +154,7 @@
final ServiceReference ref = event.getServiceReference();
final String serviceString = "Service " + m_dependencyMetadata.getInterface() + "/"
+ ref.getProperty( Constants.SERVICE_ID );
- final boolean release = m_componentManager.obtainReadLock();
+ final boolean release = m_componentManager.obtainReadLock( "DependencyManager.serviceChanged.1" );
try
{
switch ( event.getType() )
@@ -259,7 +259,7 @@
{
if ( release )
{
- m_componentManager.releaseReadLock();
+ m_componentManager.releaseReadLock( "DependencyManager.serviceChanged.1" );
}
}
}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
index 875749a..1987346 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
@@ -618,12 +618,12 @@
public Object getService( Bundle bundle, ServiceRegistration serviceRegistration )
{
- final boolean release = obtainReadLock();
+ final boolean release = obtainReadLock( "ImmediateComponentManager.getService.1" );
try
{
if ( m_useCount == 0 )
{
- escalateLock();
+ escalateLock( "ImmediateComponentManager.getService.1" );
try
{
if ( m_useCount == 0 )
@@ -639,7 +639,7 @@
}
finally
{
- deescalateLock();
+ deescalateLock( "ImmediateComponentManager.getService.1" );
}
}
m_useCount++;
@@ -649,14 +649,14 @@
{
if ( release )
{
- releaseReadLock();
+ releaseReadLock( "ImmediateComponentManager.getService.1" );
}
}
}
public void ungetService( Bundle bundle, ServiceRegistration serviceRegistration, Object o )
{
- final boolean release = obtainReadLock();
+ final boolean release = obtainReadLock( "ImmediateComponentManager.ungetService.1" );
try
{
// the framework should not call ungetService more than it calls
@@ -670,7 +670,7 @@
// be kept (FELIX-3039)
if ( m_useCount == 0 && !isImmediate() && !getActivator().getConfiguration().keepInstances() )
{
- escalateLock();
+ escalateLock( "ImmediateComponentManager.ungetService.1" );
try
{
if ( m_useCount == 0 )
@@ -680,7 +680,7 @@
}
finally
{
- deescalateLock();
+ deescalateLock( "ImmediateComponentManager.ungetService.1" );
}
}
}
@@ -689,7 +689,7 @@
{
if ( release )
{
- releaseReadLock();
+ releaseReadLock( "ImmediateComponentManager.ungetService.1" );
}
}
}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
index 4b324fb..bd3ba95 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
@@ -95,7 +95,7 @@
// When the getServiceMethod is called, the implementation object must be created
- final boolean release = obtainReadLock();
+ final boolean release = obtainReadLock( "ServiceFactoryComponentManager.getService.1" );
try
{
// private ComponentContext and implementation instances
@@ -128,7 +128,7 @@
{
if ( release )
{
- releaseReadLock();
+ releaseReadLock( "ServiceFactoryComponentManager.getService.1" );
}
}
}
@@ -142,7 +142,7 @@
log( LogService.LOG_DEBUG, "ServiceFactory.ungetService()", null );
// When the ungetServiceMethod is called, the implementation object must be deactivated
- final boolean release = obtainReadLock();
+ final boolean release = obtainReadLock( "ServiceFactoryComponentManager.ungetService.1" );
try
{
// private ComponentContext and implementation instances
@@ -161,7 +161,7 @@
{
if ( release )
{
- releaseReadLock();
+ releaseReadLock( "ServiceFactoryComponentManager.ungetService.1" );
}
}
}