FELIX-4350 Fix race between activation and deactivation. Problem with ServiceTracker exposed and ignored

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1549723 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
index 73552eb..ae4ade4 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
@@ -263,6 +263,7 @@
 
         public void removedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
         {
+            refPair.setDeleted( true );
             if ( !isOptional() )
             {
                 if (getTracker().isEmpty())
@@ -351,6 +352,7 @@
         public void removedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
         {
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleDynamic removed {2} (enter)", new Object[] {getName(), trackingCount, serviceReference}, null );
+            refPair.setDeleted( true );
             boolean unbind = isOptional() || !getTracker().isEmpty();
             if ( unbind )
             {
@@ -469,6 +471,7 @@
         public void removedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
         {
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleStaticGreedy removed {2} (enter)", new Object[] {getName(), trackingCount, serviceReference}, null );
+            refPair.setDeleted( true );
             tracked( trackingCount );
             if ( isActive() )
             {
@@ -566,6 +569,7 @@
         public void removedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
         {
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleStaticReluctant removed {2} (enter)", new Object[] {getName(), trackingCount, serviceReference}, null );
+            refPair.setDeleted( true );
             tracked( trackingCount );
             Collection<RefPair<T>> refs = this.refs.get();
             if ( isActive() && refs != null )
@@ -737,6 +741,7 @@
         public void removedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
         {
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} SingleDynamic removed {2} (enter)", new Object[] {getName(), trackingCount, serviceReference}, null );
+            refPair.setDeleted( true );
             boolean deactivate = false;
             boolean untracked = true;
             RefPair<T> oldRefPair = null;
@@ -937,6 +942,10 @@
         public void removedService( ServiceReference<T> serviceReference, RefPair<T> refPair, int trackingCount )
         {
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} SingleStatic removed {2} (enter)", new Object[] {getName(), trackingCount, serviceReference}, null );
+            if ( refPair != null ) //TODO needs investigation
+            {
+                refPair.setDeleted( true );
+            }
             this.trackingCount = trackingCount;
             tracked( trackingCount );
             boolean reactivate;
@@ -1427,7 +1436,7 @@
             new Object[]{ getName(), success, refs }, null );
         for ( RefPair<T> refPair : refs )
         {
-            if ( !refPair.isFailed() )
+            if ( !refPair.isDeleted() && !refPair.isFailed() )
             {
                 if ( !doInvokeBindMethod( componentInstance, refPair ) )
                 {
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/RefPair.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/RefPair.java
index cee9171..3f9a04a 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/RefPair.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/RefPair.java
@@ -33,6 +33,7 @@
     private AtomicReference<T> serviceObjectRef = new AtomicReference<T>();
 
     private boolean failed;
+    private volatile boolean deleted;
 
     public RefPair( ServiceReference<T> ref )
     {
@@ -74,6 +75,15 @@
         return failed;
     }
 
+    public boolean isDeleted()
+    {
+        return deleted;
+    }
+
+    public void setDeleted(boolean deleted)
+    {
+        this.deleted = deleted;
+    }
 
     @Override
     public String toString()
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java b/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java
index d22005f..97efc21 100644
--- a/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java
+++ b/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java
@@ -254,13 +254,17 @@
 
     protected static void delay()
     {
+        delay(300);
+    }
+
+    protected static void delay(int millis)
+    {
         try
         {
-            Thread.sleep( 300 );
+            Thread.sleep(millis);
         }
-        catch ( InterruptedException ie )
+        catch (InterruptedException ie)
         {
-            // dont care
         }
     }
 
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/Felix4350Test.java b/scr/src/test/java/org/apache/felix/scr/integration/Felix4350Test.java
index 57c5959..569310c 100644
--- a/scr/src/test/java/org/apache/felix/scr/integration/Felix4350Test.java
+++ b/scr/src/test/java/org/apache/felix/scr/integration/Felix4350Test.java
@@ -45,44 +45,35 @@
         // uncomment to enable debugging of this test class
 //                paxRunnerVmOption = DEBUG_VM_OPTION;
         descriptorFile = "/integration_test_FELIX_4350.xml";
-        restrictedLogging = true;
         //comment to get debug logging if the test fails.
 //        DS_LOGLEVEL = "warn";
     }
 
-    @Inject
-    protected BundleContext bundleContext;
-
     @Test
-    @Ignore
     public void test_unbind_while_activating_single_static()
     {
         doTest("SingleStatic");
     }
 
     @Test
-    @Ignore
     public void test_unbind_while_activating_single_dynamic()
     {
         doTest("SingleDynamic");
     }
 
     @Test
-    @Ignore
     public void test_unbind_while_activating_multiple_dynamic()
     {
         doTest("MultipleDynamic");
     }
 
     @Test
-    @Ignore
     public void test_unbind_while_activating_multiple_static_greedy()
     {
         doTest("MultipleStaticGreedy");
     }
 
     @Test
-    @Ignore
     public void test_unbind_while_activating_multiple_static_reluctant()
     {
         doTest("MultipleStaticReluctant");
@@ -126,15 +117,4 @@
         TestCase.assertNull(mainCompInst);
     }
 
-    protected static void delay(int millis)
-    {
-        try
-        {
-            Thread.sleep(millis);
-        }
-        catch (InterruptedException ie)
-        {
-        }
-    }
-
 }