Author: jwross
Date: Thu Oct 11 00:19:39 2012
New Revision: 1396873

URL: http://svn.apache.org/viewvc?rev=1396873&view=rev
Log:
Fixed a deadlock and some CT failures.

A deadlock existed between org.eclipse.osgi.internal.resolver.StateImpl.monitor 
and org.apache.aries.subsystem.core.Activator. It occurred when one thread was 
initializing the root subsystem, had a lock on the Activator, and needed a lock 
on the monitor as part of installing the region context bundle. Another thread 
was loading a class with dynamic imports, kicked off a resolution that grabbed 
the monitor lock, and ended up calling the SubsystemResolverHook which needed a 
lock on the Activator. The fix was to remove the need for the Activator lock in 
the SubsystemResolverHook.

1LKDEADLOCK    Deadlock detected !!!
NULL           ---------------------
NULL           
2LKDEADLOCKTHR  Thread "RMI TCP Connection(1)-127.0.0.1" (0x00007F19AC006F00)
3LKDEADLOCKWTR    is waiting for:
4LKDEADLOCKMON      sys_mon_t:0x00007F199C018240 infl_mon_t: 0x00007F199C0182B0:
4LKDEADLOCKOBJ      
org/apache/aries/subsystem/core/internal/Activator@0x00007F19FD746DB8/0x00007F19FD746DD0:
 
3LKDEADLOCKOWN    which is owned by:
2LKDEADLOCKTHR  Thread "Blueprint Extender: 1" (0x00007F19A855BD00)
3LKDEADLOCKWTR    which is waiting for:
4LKDEADLOCKMON      sys_mon_t:0x00007F199C018380 infl_mon_t: 0x00007F199C0183F0:
4LKDEADLOCKOBJ      java/lang/Object@0x00007F19FD40ED60/0x00007F19FD40ED78: 
3LKDEADLOCKOWN    which is owned by:
2LKDEADLOCKTHR  Thread "RMI TCP Connection(1)-127.0.0.1" (0x00007F19AC006F00)

Also fixed some CT failures caused by the 
org.apache.aries.subsystem.core.Location class. The location string can be 
anything so we must handle it rather than throwing an exception.

Modified:
    
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Activator.java
    
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Location.java
    
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResolverHook.java
    
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResolverHookFactory.java
    
aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/RootSubsystemTest.java

Modified: 
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Activator.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Activator.java?rev=1396873&r1=1396872&r2=1396873&view=diff
==============================================================================
--- 
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Activator.java
 (original)
+++ 
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Activator.java
 Thu Oct 11 00:19:39 2012
@@ -153,8 +153,6 @@ public class Activator implements Bundle
                        instance = Activator.this;
                }
                registerBundleEventHook();
-               
registrations.add(bundleContext.registerService(ResolverHookFactory.class, new 
SubsystemResolverHookFactory(), null));
-               registrar = new SubsystemServiceRegistrar(bundleContext);
                try {
                        subsystems = new Subsystems();
                }
@@ -164,6 +162,8 @@ public class Activator implements Bundle
                catch (Exception e) {
                        throw new SubsystemException(e);
                }
+               
registrations.add(bundleContext.registerService(ResolverHookFactory.class, new 
SubsystemResolverHookFactory(subsystems), null));
+               registrar = new SubsystemServiceRegistrar(bundleContext);
                AriesSubsystem root = subsystems.getRootSubsystem();
                root.start();
        }
@@ -263,8 +263,8 @@ public class Activator implements Bundle
                                activate();
                        }
                }
-    else if (service instanceof IDirectoryFinder)
-      finders.add((IDirectoryFinder)service);
+               else if (service instanceof IDirectoryFinder)
+                       finders.add((IDirectoryFinder)service);
                else
                        repositories.add((Repository)service);
                return service;
@@ -304,13 +304,13 @@ public class Activator implements Bundle
                else if (service instanceof ModelledResourceManager) {
                        if (service.equals(modelledResourceManager)) {
                                ModelledResourceManager modelledResourceManager 
= 
(ModelledResourceManager)findAlternateServiceFor(this.modelledResourceManager);
-                               if (resolver == null)
+                               if (modelledResourceManager == null)
                                        deactivate();
                                this.modelledResourceManager = 
modelledResourceManager;
                        }
                }
-    else if (service instanceof IDirectoryFinder)
-      finders.remove(service);
+               else if (service instanceof IDirectoryFinder)
+                       finders.remove(service);
                else
                        repositories.remove(service);
        }

Modified: 
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Location.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Location.java?rev=1396873&r1=1396872&r2=1396873&view=diff
==============================================================================
--- 
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Location.java
 (original)
+++ 
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Location.java
 Thu Oct 11 00:19:39 2012
@@ -31,7 +31,7 @@ import org.osgi.framework.Version;
 
 public class Location {
   enum LocationType {
-    SUBSYSTEM("subsystem", "subsystem"), IDIRFINDER(IDIR_SCHEME, IDIR_SCHEME), 
URL("url", null);
+    SUBSYSTEM("subsystem", "subsystem"), IDIRFINDER(IDIR_SCHEME, IDIR_SCHEME), 
URL("url", null), UNKNOWN("unknown", null);
     final String toString;
     final String scheme;
     LocationType(String toString, String scheme) {this.toString = toString; 
this.scheme = scheme;}
@@ -70,7 +70,10 @@ public class Location {
         uri = locationUri;
       }
     } else {
-      throw new IllegalArgumentException(location + " is not an absolute uri");
+       type = LocationType.UNKNOWN;
+       url = null;
+       uri = null;
+       subsystemUri = null;
     }
   }
     
@@ -96,6 +99,11 @@ public class Location {
           return FileSystem.getFSRoot(new File(uri));
         else
           return FileSystem.getFSRoot(url.openStream());
+      case UNKNOWN:
+         // Only try to create a URL with the location value here. If the
+         // location was just a string and an InputStream was provided, this
+         // method will never be called.
+         return FileSystem.getFSRoot(new URL(value).openStream());
       default : // should never get here as switch should cover all types
         throw new UnsupportedOperationException("cannot open location of type 
" + type); 
     }

Modified: 
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResolverHook.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResolverHook.java?rev=1396873&r1=1396872&r2=1396873&view=diff
==============================================================================
--- 
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResolverHook.java
 (original)
+++ 
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResolverHook.java
 Thu Oct 11 00:19:39 2012
@@ -30,6 +30,14 @@ import org.slf4j.LoggerFactory;
 public class SubsystemResolverHook implements ResolverHook {
        private static final Logger LOGGER = 
LoggerFactory.getLogger(SubsystemResolverHook.class);
        
+       private final Subsystems subsystems;
+       
+       public SubsystemResolverHook(Subsystems subsystems) {
+               if (subsystems == null)
+                       throw new NullPointerException("Missing required 
parameter: subsystems");
+               this.subsystems = subsystems;
+       }
+       
        public void end() {
                // noop
        }
@@ -39,7 +47,7 @@ public class SubsystemResolverHook imple
                // there is at least one preferred provider.
                // (1) Find the subsystem(s) containing 
requirement.getResource() as a
                // constituent.
-               Collection<AriesSubsystem> requirers = 
Activator.getInstance().getSubsystems().getSubsystemsReferencing(requirement.getResource());
+               Collection<AriesSubsystem> requirers = 
subsystems.getSubsystemsReferencing(requirement.getResource());
                // (2) For each candidate, ask each subsystem if the candidate 
or any of
                // the candidate's containing subsystems is a preferred 
provider. If at
                // least one preferred provider exists, filter out all other 
candidates
@@ -62,7 +70,7 @@ public class SubsystemResolverHook imple
                                if 
(revision.getSymbolicName().startsWith(Constants.RegionContextBundleSymbolicNamePrefix))
                                        // Don't want to filter out the region 
context bundle.
                                        continue;
-                               Collection<AriesSubsystem> subsystems = 
Activator.getInstance().getSubsystems().getSubsystemsReferencing(revision);
+                               Collection<AriesSubsystem> subsystems = 
this.subsystems.getSubsystemsReferencing(revision);
                                for (AriesSubsystem subsystem : subsystems) {
                                        if (subsystem.isFeature()) {
                                                // Feature subsystems require 
no isolation.
@@ -87,7 +95,7 @@ public class SubsystemResolverHook imple
        }
        
        private boolean isResourceConstituentOfPreferredSubsystem(Resource 
resource, AriesSubsystem preferer) {
-               Collection<AriesSubsystem> subsystems = 
Activator.getInstance().getSubsystems().getSubsystemsReferencing(resource);
+               Collection<AriesSubsystem> subsystems = 
this.subsystems.getSubsystemsReferencing(resource);
                for (AriesSubsystem subsystem : subsystems)
                        if 
(preferer.getSubsystemManifest().getPreferredProviderHeader().contains(subsystem))
                                return true;

Modified: 
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResolverHookFactory.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResolverHookFactory.java?rev=1396873&r1=1396872&r2=1396873&view=diff
==============================================================================
--- 
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResolverHookFactory.java
 (original)
+++ 
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResolverHookFactory.java
 Thu Oct 11 00:19:39 2012
@@ -20,7 +20,14 @@ import org.osgi.framework.hooks.resolver
 import org.osgi.framework.wiring.BundleRevision;
 
 public class SubsystemResolverHookFactory implements ResolverHookFactory {
+       private final Subsystems subsystems;
+       public SubsystemResolverHookFactory(Subsystems subsystems) {
+               if (subsystems == null)
+                       throw new NullPointerException("Missing required 
parameter: subsystems");
+               this.subsystems = subsystems;
+       }
+       
        public ResolverHook begin(Collection<BundleRevision> triggers) {
-               return new SubsystemResolverHook();
+               return new SubsystemResolverHook(subsystems);
        }
 }

Modified: 
aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/RootSubsystemTest.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/RootSubsystemTest.java?rev=1396873&r1=1396872&r2=1396873&view=diff
==============================================================================
--- 
aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/RootSubsystemTest.java
 (original)
+++ 
aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/RootSubsystemTest.java
 Thu Oct 11 00:19:39 2012
@@ -79,6 +79,11 @@ public class RootSubsystemTest extends S
        public void testServiceEvents() throws Exception {
                Subsystem root = getRootSubsystem();
                Bundle core = getSubsystemCoreBundle();
+               // TODO Temporary(?) workaround to allow time for any tardy 
service
+               // events to arrive so they can be cleared. So far, this sleep 
has only
+               // been necessary on the IBM 6.0 64-bit JDK.
+               Thread.sleep(1000);
+               subsystemEvents.clear();
                core.stop();
                assertServiceEventsStop(root);
                core.uninstall();


Reply via email to