Do not hold lock while firing RESOLVED event. (FELIX-2597)


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@997459 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/Felix.java b/framework/src/main/java/org/apache/felix/framework/Felix.java
index 4ca7f7f..9604a69 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -3956,6 +3956,7 @@
                         "Unable to acquire global lock for resolve.", rootModule, null);
                 }
 
+                Map<Module, List<Wire>> wireMap = null;
                 try
                 {
                     BundleImpl bundle = (BundleImpl) rootModule.getBundle();
@@ -3983,8 +3984,7 @@
                             try
                             {
                                 // Resolve the module.
-                                Map<Module, List<Wire>> wireMap =
-                                    m_resolver.resolve(m_resolverState, newRootModule);
+                                wireMap = m_resolver.resolve(m_resolverState, newRootModule);
 
                                 // Mark all modules as resolved.
                                 markResolvedModules(wireMap);
@@ -4015,6 +4015,8 @@
                     // Always release the global lock.
                     releaseGlobalLock();
                 }
+
+                fireResolvedEvents(wireMap);
             }
         }
 
@@ -4036,6 +4038,7 @@
                         "Unable to acquire global lock for resolve.", module, null);
                 }
 
+                Map<Module, List<Wire>> wireMap = null;
                 try
                 {
                     // Double check to make sure that someone hasn't beaten us to
@@ -4051,8 +4054,7 @@
                         }
                     }
 
-                    Map<Module, List<Wire>> wireMap =
-                        m_resolver.resolve(m_resolverState, module, pkgName);
+                    wireMap = m_resolver.resolve(m_resolverState, module, pkgName);
 
                     if ((wireMap != null) && wireMap.containsKey(module))
                     {
@@ -4078,6 +4080,8 @@
                     // Always release the global lock.
                     releaseGlobalLock();
                 }
+
+                fireResolvedEvents(wireMap);
             }
 
             return candidateWire;
@@ -4196,7 +4200,6 @@
             BundleImpl bundle = (BundleImpl) module.getBundle();
 
             // Lock the bundle first.
-            boolean fire = false;
             try
             {
                 // Acquire bundle lock.
@@ -4219,7 +4222,6 @@
                     else
                     {
                         setBundleStateAndNotify(bundle, Bundle.RESOLVED);
-                        fire = true;
                     }
                 }
             }
@@ -4227,11 +4229,27 @@
             {
                 releaseBundleLock(bundle);
             }
+        }
 
-            // Fire event while not holding the bundle lock.
-            if (fire)
+        private void fireResolvedEvents(Map<Module, List<Wire>> wireMap)
+        {
+            if (wireMap != null)
             {
-                fireBundleEvent(BundleEvent.RESOLVED, bundle);
+                Iterator<Entry<Module, List<Wire>>> iter = wireMap.entrySet().iterator();
+                // Iterate over the map to fire necessary RESOLVED events.
+                while (iter.hasNext())
+                {
+                    Entry<Module, List<Wire>> entry = iter.next();
+                    Module module = entry.getKey();
+
+                    // Fire RESOLVED events for all fragments.
+                    List<Module> fragments = ((ModuleImpl) module).getFragments();
+                    for (int i = 0; (fragments != null) && (i < fragments.size()); i++)
+                    {
+                        fireBundleEvent(BundleEvent.RESOLVED, fragments.get(i).getBundle());
+                    }
+                    fireBundleEvent(BundleEvent.RESOLVED, module.getBundle());
+                }
             }
         }
     }