FELIX-4350 Close stuff more definitely on failed activation

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1550015 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
index fa112dd..4b109c9 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
@@ -928,17 +928,14 @@
             obtainStateLock( "AbstractComponentManager.State.doDeactivate.1" );
             try
             {
-                if ( m_activated )
+                m_activated = false;
+                deleteComponent( reason );
+                deactivateDependencyManagers();
+                if ( disable )
                 {
-                    m_activated = false;
-                    deleteComponent( reason );
-                    deactivateDependencyManagers();
-                    if ( disable )
-                    {
-                        disableDependencyManagers();
-                    }
-                    unsetDependenciesCollected();
+                    disableDependencyManagers();
                 }
+                unsetDependenciesCollected();
             }
             finally
             {
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 1ba82f6..c502f10 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
@@ -202,6 +202,15 @@
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracker opened", new Object[] {getName()}, null );
         }
 
+        protected void deactivateTracker()
+        {
+            ServiceTracker<T, RefPair<T>> tracker = getTracker();
+            if ( tracker != null )
+            {
+                tracker.deactivate();
+            }
+        }
+
         protected Map<ServiceReference<T>, RefPair<T>> getPreviousRefMap()
         {
             return previousRefMap;
@@ -283,7 +292,7 @@
 
         public void close()
         {
-            getTracker().deactivate();
+            deactivateTracker();
         }
 
         public Collection<RefPair<T>> getRefs( AtomicInteger trackingCount )
@@ -315,6 +324,7 @@
             {
                 if (isActive())
                 {
+                    m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleDynamic already active, binding {2}", new Object[] {getName(), trackingCount, serviceReference}, null );
                     getServiceObject( m_bindMethods.getBind(), refPair );
                     if ( !refPair.isFailed() )
                     {
@@ -326,10 +336,15 @@
                 }
                 else if ( isTrackerOpened() && !isOptional() )
                 {
+                    m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleDynamic, activating", new Object[] {getName(), trackingCount}, null );
                     tracked( trackingCount );
                     tracked = true;
                     m_componentManager.activateInternal( trackingCount );
                 }
+                else 
+                {
+                    m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleDynamic, inactive, doing nothing: tracker opened: {2}, optional: {3}", new Object[] {getName(), trackingCount, isTrackerOpened(), isOptional()}, null );                    
+                }
             }
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} MultipleDynamic added {2} (exit)", new Object[] {getName(), trackingCount, serviceReference}, null );
             if ( !tracked )
@@ -401,7 +416,7 @@
             {
                 ungetService( ref );
             }
-            getTracker().deactivate();
+            deactivateTracker();
         }
 
 
@@ -519,7 +534,7 @@
             {
                 ungetService( ref );
             }
-            getTracker().deactivate();
+            deactivateTracker();
         }
 
         public Collection<RefPair<T>> getRefs( AtomicInteger trackingCount )
@@ -645,7 +660,7 @@
                     ungetService( ref );
                 }
             }
-            getTracker().deactivate();
+            deactivateTracker();
         }
 
         public Collection<RefPair<T>> getRefs( AtomicInteger trackingCount )
@@ -847,7 +862,7 @@
         public void close()
         {
             closeRefPair();
-            getTracker().deactivate();
+            deactivateTracker();
         }
 
         private void closeRefPair()
@@ -949,10 +964,20 @@
             synchronized (getTracker().tracked())
             {
                 reactivate = ( isActive() && refPair == this.refPair) || ( !isOptional() && getTracker().isEmpty());
+                if (!reactivate && refPair == this.refPair) {
+                    this.refPair = null;
+                }
             }
             if ( reactivate )
             {
                 m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false, false );
+                synchronized ( getTracker().tracked() )
+                {
+                    if (refPair == this.refPair)
+                    {
+                        this.refPair = null;
+                    }
+                }
                 m_componentManager.activateInternal( trackingCount );
             }
             m_componentManager.log( LogService.LOG_DEBUG, "dm {0} tracking {1} SingleStatic removed {2} (exit)", new Object[] {getName(), trackingCount, serviceReference}, null );
@@ -989,17 +1014,21 @@
 
         public void close()
         {
-            RefPair<T> ref;
-            synchronized ( getTracker().tracked() )
+            ServiceTracker<T, RefPair<T>> tracker = getTracker();
+            if ( tracker != null )
             {
-                ref = refPair;
-                refPair = null;
+                RefPair<T> ref;
+                synchronized ( tracker.tracked() )
+                {
+                    ref = refPair;
+                    refPair = null;
+                }
+                if ( ref != null )
+                {
+                    ungetService( ref );
+                }
+                tracker.deactivate();
             }
-            if ( ref != null )
-            {
-                ungetService( ref );
-            }
-            getTracker().deactivate();
         }
 
         public Collection<RefPair<T>> getRefs( AtomicInteger trackingCount )
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java
index 8838314..b92105c 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java
@@ -303,8 +303,10 @@
                 {
                     md.close( implementationObject, componentContext.getEdgeInfo( md ) );
                 }
+                md.deactivate();
             }
             setter.resetImplementationObject( implementationObject );
+            unsetDependenciesCollected();
             return null;
 
         }
@@ -344,21 +346,23 @@
         componentContext.setImplementationAccessible( false );
         S implementationObject = componentContext.getImplementationObject( false );
 
-        // 1. Call the deactivate method, if present
-        // don't care for the result, the error (acccording to 112.5.12 If the deactivate
-        // method throws an exception, SCR must log an error message containing the
-        // exception with the Log Service and continue) has already been logged
-        final MethodResult result = getComponentMethods().getDeactivateMethod().invoke( implementationObject, new ActivatorParameter( componentContext,
-                reason ), null, this );
-        if ( result != null )
+        if ( implementationObject != null )
         {
-            setServiceProperties( result );
-        }
-
-        // 2. Unbind any bound services
-        for ( DependencyManager md: getReversedDependencyManagers() )
-        {
-            md.close( implementationObject, componentContext.getEdgeInfo( md ) );
+            // 1. Call the deactivate method, if present
+            // don't care for the result, the error (acccording to 112.5.12 If the deactivate
+            // method throws an exception, SCR must log an error message containing the
+            // exception with the Log Service and continue) has already been logged
+            final MethodResult result = getComponentMethods().getDeactivateMethod().invoke( implementationObject,
+                    new ActivatorParameter( componentContext, reason ), null, this );
+            if ( result != null )
+            {
+                setServiceProperties( result );
+            }
+            // 2. Unbind any bound services
+            for ( DependencyManager md: getReversedDependencyManagers() )
+            {
+                md.close( implementationObject, componentContext.getEdgeInfo( md ) );
+            }
         }
 
     }