Ensure that the threadpool is shot down when test is done

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1461515 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/dependencymanager/test/src/test/java/org/apache/felix/dm/test/RaceTest.java b/dependencymanager/test/src/test/java/org/apache/felix/dm/test/RaceTest.java
index 5ae7636..94e8ae5 100644
--- a/dependencymanager/test/src/test/java/org/apache/felix/dm/test/RaceTest.java
+++ b/dependencymanager/test/src/test/java/org/apache/felix/dm/test/RaceTest.java
@@ -26,6 +26,8 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 
 import junit.framework.Assert;
@@ -55,29 +57,45 @@
 
     static volatile CountDownLatch m_bindALatch;
     static volatile CountDownLatch m_unbindALatch;
-    static final Executor m_exec = Executors.newFixedThreadPool(10);
+    volatile ThreadPoolExecutor m_exec;
     static volatile BundleContext m_bctx;
     volatile boolean m_running = true;
+    volatile CountDownLatch m_stopLatch = new CountDownLatch(1);
 
     @Test
     public void testConcurrentInjections(BundleContext ctx) {
-        m_bctx = ctx;
-        DependencyManager m = new DependencyManager(ctx);
-        Component controller = m
-                .createComponent()
-                .setImplementation(Controller.class)
-                .setComposition("getComposition")
-                .add(m.createServiceDependency().setService(A.class).setCallbacks("bindA", "unbindA")
-                        .setRequired(true));
+        m_exec = new ThreadPoolExecutor(10, 10, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
+        try {
+            m_bctx = ctx;
+            DependencyManager m = new DependencyManager(ctx);
+            Component controller = m
+                    .createComponent()
+                    .setImplementation(Controller.class)
+                    .setComposition("getComposition")
+                    .add(m.createServiceDependency().setService(A.class).setCallbacks("bindA", "unbindA")
+                            .setRequired(true));
 
-        m.add(controller);
-        Thread t = new Thread(this);
-        t.start();
-        super.sleep(10000);
+            m.add(controller);
+            Thread t = new Thread(this);
+            t.start();
+            super.sleep(10000);
 
-        m_running = false;
-        t.interrupt();
-        Assert.assertFalse("Test failed.", super.errorsLogged());
+            m_running = false;
+            t.interrupt();
+            m_stopLatch.await(5000, TimeUnit.MILLISECONDS);
+            Assert.assertFalse("Test failed.", super.errorsLogged());            
+        } 
+        
+        catch (Throwable t) {
+            t.printStackTrace();
+        }
+        finally {
+            m_exec.shutdown();
+            try {
+                m_exec.awaitTermination(5, TimeUnit.SECONDS);
+            } catch (InterruptedException e) {
+            }
+        }
     }
 
     public void run() {
@@ -100,7 +118,7 @@
                 }
 
                 aFactory.unregister(N, m_exec);
-                
+
                 if (!m_unbindALatch.await(5000, TimeUnit.MILLISECONDS)) {
                     super.log(LOG_ERROR, "unbind problem.");
                     return;
@@ -116,6 +134,9 @@
             super.log(LOG_ERROR, "error", t);
             return;
         }
+        finally {
+            m_stopLatch.countDown();
+        }
     }
 
     public static class A {
@@ -148,8 +169,10 @@
                     public void run() {
                         try {
                             ServiceRegistration sr = m_regs.poll();
-                            sr.unregister();
-                            m_unbindALatch.countDown();
+                            if (sr != null) {
+                                sr.unregister();
+                                m_unbindALatch.countDown();
+                            }
                         } catch (Throwable e) {
                             log(LOG_ERROR, "error", e);
                         }