FELIX-3456 Track how lock was obtained, and try to do a thread dump on lock problems
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1371288 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/pom.xml b/scr/pom.xml
index 7d05057..1698d37 100644
--- a/scr/pom.xml
+++ b/scr/pom.xml
@@ -331,6 +331,9 @@
<ignore>java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock</ignore>
<ignore>java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock</ignore>
<ignore>java.util.concurrent.TimeUnit</ignore>
+ <ignore>java.lang.management.ManagementFactory</ignore>
+ <ignore>java.lang.management.ThreadInfo</ignore>
+ <ignore>java.lang.management.ThreadMXBean</ignore>
</ignores>
</configuration>
<executions>
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 97b5265..732ba01 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
@@ -18,6 +18,9 @@
*/
package org.apache.felix.scr.impl.manager;
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
import java.security.Permission;
import java.util.ArrayList;
import java.util.Arrays;
@@ -31,7 +34,6 @@
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantReadWriteLock;
-import EDU.oswego.cs.dl.util.concurrent.ReaderPreferenceReadWriteLock;
import org.apache.felix.scr.Component;
import org.apache.felix.scr.Reference;
import org.apache.felix.scr.impl.BundleComponentActivator;
@@ -97,6 +99,9 @@
private long m_timeout = 5000;
+ private Thread lockingThread;
+ private Throwable lockingStackTrace;
+
/**
* The constructor receives both the activator and the metadata
*
@@ -162,7 +167,15 @@
{
if (!m_stateLock.tryReadLock( m_timeout ) )
{
- throw new IllegalStateException( "Could not obtain lock in " + m_timeout + " milliseconds for component " + m_componentMetadata.getName() );
+ try
+ {
+ dumpThreads();
+ }
+ catch ( Throwable e )
+ {
+ //we are on a pre 1.6 vm, no worries
+ }
+ throw ( IllegalStateException ) new IllegalStateException( "Could not obtain lock in " + m_timeout + " milliseconds for component " + m_componentMetadata.getName() ).initCause( lockingStackTrace );
}
}
catch ( InterruptedException e )
@@ -188,6 +201,8 @@
{
throw new IllegalStateException( "Could not obtain lock" );
}
+ lockingThread = Thread.currentThread();
+ lockingStackTrace = new Exception("Write lock stack trace for thread: " + lockingThread);
}
catch ( InterruptedException e )
{
@@ -199,6 +214,8 @@
final void deescalateLock()
{
m_stateLock.deescalate();
+ lockingThread = null;
+ lockingStackTrace = null;
}
final void checkLocked()
@@ -214,6 +231,18 @@
return m_stateLock.getWriteHoldCount() > 0;
}
+ private void dumpThreads()
+ {
+ ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
+ StringBuffer b = new StringBuffer( "Thread dump\n" );
+ ThreadInfo[] infos = threadMXBean.dumpAllThreads( threadMXBean.isObjectMonitorUsageSupported(), threadMXBean.isSynchronizerUsageSupported() );
+ for ( int i = 0; i < infos.length; i++ )
+ {
+ b.append( infos[i] ).append( "\n\n" );
+ }
+ log( LogService.LOG_INFO, b.toString(), null );
+ }
+
//---------- Component ID management
void registerComponentId()