FELIX-314 EventDispatcher class not reusable in same class loader for multiple Felix instances

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@551911 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 6b46608..5e0d5d8 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -336,7 +336,7 @@
         m_policyCore.setModuleFactory(m_factory);
 
         // Initialize event dispatcher.
-        m_dispatcher = new EventDispatcher(m_logger);
+        m_dispatcher = EventDispatcher.start(m_logger);
 
         // Initialize framework properties.
         initializeFrameworkProperties();
diff --git a/framework/src/main/java/org/apache/felix/framework/util/EventDispatcher.java b/framework/src/main/java/org/apache/felix/framework/util/EventDispatcher.java
index 24dff80..bc74f84 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/EventDispatcher.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/EventDispatcher.java
@@ -49,6 +49,7 @@
     // A single thread is used to deliver events for all dispatchers.
     private static Thread m_thread = null;
     private static String m_threadLock = "thread lock";
+    private static int m_references = 0;
     private static boolean m_stopping = false;
     private static boolean m_stopped = false;
     // List of requests.
@@ -56,9 +57,14 @@
     // Pooled requests to avoid memory allocation.
     private static final ArrayList m_requestPool = new ArrayList();
 
-    public EventDispatcher(Logger logger)
+    private EventDispatcher(Logger logger)
     {
         m_logger = logger;
+    }
+
+    public static EventDispatcher start(Logger logger)
+    {
+        EventDispatcher eventDispatcher = new EventDispatcher(logger);
 
         synchronized (m_threadLock)
         {
@@ -73,9 +79,16 @@
                 }, "FelixDispatchQueue");
                 m_thread.start();
             }
-        }
-    }
 
+            // reference counting and flags
+            m_references++;
+            m_stopping = false;
+            m_stopped = false;
+        }
+
+        return eventDispatcher;
+    }
+    
     public static void shutdown()
     {
         synchronized (m_threadLock)
@@ -86,6 +99,13 @@
                 return;
             }
 
+            // decrement use counter, don't continue if there are users
+            m_references--;
+            if (m_references > 0)
+            {
+                return;
+            }
+            
             // Signal dispatch thread.
             m_stopping = true;
             synchronized (m_requestList)
@@ -104,6 +124,9 @@
                 {
                 }
             }
+            
+            // remove the thread reference
+            m_thread = null;
         }
     }