Move thread for shutting down framework further out to avoid
potential deadlock when a bundle tries to stop the framework
during framework startup. (FELIX-1816)


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1080350 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 b4794d4..f75d8ca 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -162,8 +162,7 @@
     private final String[] m_bootPkgs;
     private final boolean[] m_bootPkgWildcards;
 
-    // Shutdown thread.
-    private Thread m_shutdownThread = null;
+    // Shutdown gate.
     private volatile ThreadGate m_shutdownGate = null;
     
     // Security Manager created by the framework
@@ -867,7 +866,24 @@
                 AdminPermission.EXECUTE));
         }
 
-        stopBundle(this, true);
+        // Spec says stop() on SystemBundle should return immediately and
+        // shutdown framework on another thread.
+        new Thread(new Runnable() {
+            public void run()
+            {
+                try
+                {
+                    stopBundle(Felix.this, true);
+                }
+                catch (BundleException ex)
+                {
+                    m_logger.log(
+                        Logger.LOG_ERROR,
+                        "Exception trying to stop framework.",
+                        ex);
+                }
+            }
+        }, "FelixShutdown").start();
     }
 
     public void stop(int options) throws BundleException
@@ -4370,7 +4386,7 @@
         }
     }
 
-    class SystemBundleActivator implements BundleActivator, Runnable
+    class SystemBundleActivator implements BundleActivator
     {
         public void start(BundleContext context) throws Exception
         {
@@ -4391,18 +4407,6 @@
 
         public void stop(BundleContext context)
         {
-            // Spec says stop() on SystemBundle should return immediately and
-            // shutdown framework on another thread.
-            if (m_shutdownThread == null)
-            {
-                // Initial call of stop, so kick off shutdown.
-                m_shutdownThread = new Thread(this, "FelixShutdown");
-                m_shutdownThread.start();
-            }
-        }
-
-        public void run()
-        {
             // The state of the framework should be STOPPING, so
             // acquire the bundle lock to verify it.
             acquireBundleLock(Felix.this, Bundle.STOPPING);
@@ -4522,7 +4526,6 @@
                 setBundleStateAndNotify(Felix.this, Bundle.RESOLVED);
                 m_shutdownGate.open();
                 m_shutdownGate = null;
-                m_shutdownThread = null;
             }
             finally
             {