You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by pa...@apache.org on 2014/07/09 11:56:54 UTC
svn commit: r1609073 -
/felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlers.java
Author: pauls
Date: Wed Jul 9 09:56:54 2014
New Revision: 1609073
URL: http://svn.apache.org/r1609073
Log:
Fix a deadlock in URLHandlers when Felix.init and Felix.stop are called concurrently (FELIX-4523).
Modified:
felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlers.java
Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlers.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlers.java?rev=1609073&r1=1609072&r2=1609073&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlers.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlers.java Wed Jul 9 09:56:54 2014
@@ -87,7 +87,7 @@ class URLHandlers implements URLStreamHa
// This maps classloaders of URLHandlers in other classloaders to lists of
// their frameworks.
- private static Map m_classloaderToFrameworkLists = new HashMap();
+ private final static Map m_classloaderToFrameworkLists = new HashMap();
// The list to hold all enabled frameworks registered with this handlers
private static final List m_frameworks = new ArrayList();
@@ -586,6 +586,7 @@ class URLHandlers implements URLStreamHa
**/
public static void registerFrameworkInstance(Object framework, boolean enable)
{
+ boolean register = false;
synchronized (m_frameworks)
{
// If the URL Handlers service is not going to be enabled,
@@ -595,13 +596,38 @@ class URLHandlers implements URLStreamHa
// We need to create an instance if this is the first
// time this method is called, which will set the handler
// factories.
- if (m_handler == null)
+ if (m_handler == null )
{
- m_handler = new URLHandlers();
+ register = true;
+ }
+ else
+ {
+ m_frameworks.add(framework);
+ m_counter++;
+ }
+ }
+ else
+ {
+ m_counter++;
+ }
+ }
+ if (register)
+ {
+ synchronized (URL.class)
+ {
+ synchronized (m_classloaderToFrameworkLists)
+ {
+ synchronized (m_frameworks)
+ {
+ if (m_handler == null )
+ {
+ m_handler = new URLHandlers();
+ }
+ m_frameworks.add(framework);
+ m_counter++;
+ }
}
- m_frameworks.add(framework);
}
- m_counter++;
}
}
@@ -618,32 +644,55 @@ class URLHandlers implements URLStreamHa
boolean unregister = false;
synchronized (m_frameworks)
{
- m_counter--;
- if (m_frameworks.remove(framework))
+ if (m_frameworks.contains(framework))
{
- if (m_frameworks.isEmpty())
+ if (m_frameworks.size() == 1 && m_handler != null)
{
unregister = true;
- m_handler = null;
+ }
+ else
+ {
+ m_frameworks.remove(framework);
+ m_counter--;
}
}
+ else
+ {
+ m_counter--;
+ }
}
if (unregister)
{
- try
- {
- m_secureAction.invoke(m_secureAction.getDeclaredMethod(
- m_rootURLHandlers.getClass(),
- "unregisterFrameworkListsForContextSearch",
- new Class[]{ ClassLoader.class}),
- m_rootURLHandlers,
- new Object[] {URLHANDLERS_CLASS.getClassLoader()});
- }
- catch (Exception e)
- {
- // This should not happen
- e.printStackTrace();
- }
+ synchronized (URL.class)
+ {
+ synchronized (m_classloaderToFrameworkLists)
+ {
+ synchronized (m_frameworks)
+ {
+ m_frameworks.remove(framework);
+ m_counter--;
+ if (m_frameworks.isEmpty() && m_handler != null)
+ {
+
+ m_handler = null;
+ try
+ {
+ m_secureAction.invoke(m_secureAction.getDeclaredMethod(
+ m_rootURLHandlers.getClass(),
+ "unregisterFrameworkListsForContextSearch",
+ new Class[]{ ClassLoader.class}),
+ m_rootURLHandlers,
+ new Object[] {URLHANDLERS_CLASS.getClassLoader()});
+ }
+ catch (Exception e)
+ {
+ // This should not happen
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
}
}