You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by dj...@apache.org on 2013/09/16 09:39:24 UTC

svn commit: r1523551 - in /felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager: AbstractComponentManager.java DependencyManager.java EdgeInfo.java ImmediateComponentManager.java ServiceFactoryComponentManager.java

Author: djencks
Date: Mon Sep 16 07:39:24 2013
New Revision: 1523551

URL: http://svn.apache.org/r1523551
Log:
FELIX-4223 document service event tracking, start code cleanup on way to avoiding collisions between config updates and activation/deactivation

Modified:
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/EdgeInfo.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java?rev=1523551&r1=1523550&r2=1523551&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java Mon Sep 16 07:39:24 2013
@@ -264,6 +264,11 @@ public abstract class AbstractComponentM
         }
     }
 
+    /**
+     * We effectively maintain the set of completely processed service event tracking counts.  This method waits for all events prior 
+     * to the parameter tracking count to complete, then returns.  See further documentation in EdgeInfo.
+     * @param trackingCount
+     */
     void waitForTracked( int trackingCount )
     {
         m_missingLock.lock();
@@ -785,7 +790,6 @@ public abstract class AbstractComponentM
             disposeInternal( reason );
             return;
         }
-        m_activated = false;
         log( LogService.LOG_DEBUG, "Deactivating component", null );
 
         // catch any problems from deleting the component to prevent the
@@ -821,7 +825,6 @@ public abstract class AbstractComponentM
         log( LogService.LOG_DEBUG, "Disposing component (reason: " + reason + ")", null );
         if ( m_activated )
         {
-            m_activated = false;
             doDeactivate( reason, true );
         }
         clear();
@@ -840,6 +843,7 @@ public abstract class AbstractComponentM
             obtainWriteLock( "AbstractComponentManager.State.doDeactivate.1" );
             try
             {
+                m_activated = false;
                 deleteComponent( reason );
                 deactivateDependencyManagers();
                 if ( disable )
@@ -1090,7 +1094,6 @@ public abstract class AbstractComponentM
         if ( m_activator != null )
         {
             m_activator.unregisterComponentId( this );
-//            m_activator = null;
         }
     }
 
@@ -1270,9 +1273,10 @@ public abstract class AbstractComponentM
     private void disableDependencyManagers()
     {
         log( LogService.LOG_DEBUG, "Disabling dependency managers", null);
+        AtomicInteger trackingCount = new AtomicInteger();
         for ( DependencyManager<S, ?> dm: getDependencyManagers() )
         {
-            dm.unregisterServiceListener();
+            dm.unregisterServiceListener( trackingCount );
         }
     }
 

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java?rev=1523551&r1=1523550&r2=1523551&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java Mon Sep 16 07:39:24 2013
@@ -1680,6 +1680,7 @@ public class DependencyManager<S, T> imp
         // null. This is valid for both immediate and delayed components
         if ( componentInstance != null )
         {
+            //TODO needs sync on getTracker().tracked()
             if (info.outOfRange( trackingCount ) )
             {
                 //wait for unbinds to complete
@@ -1885,7 +1886,13 @@ public class DependencyManager<S, T> imp
         }
 
         final ServiceTracker<T, RefPair<T>> oldTracker = m_tracker;
-        SortedMap<ServiceReference<T>, RefPair<T>> refMap = unregisterServiceListener();
+        AtomicInteger trackingCount = new AtomicInteger();
+        SortedMap<ServiceReference<T>, RefPair<T>> refMap = unregisterServiceListener( trackingCount );
+        if ( trackingCount.get() != -1 )
+        {
+            //wait for service events to complete before processing initial set from new tracker.
+            m_componentManager.waitForTracked( trackingCount.get() );
+        }
         m_componentManager.log( LogService.LOG_DEBUG, "Setting target property for dependency {0} to {1}", new Object[]
                 {getName(), target}, null );
         BundleContext bundleContext = m_componentManager.getBundleContext();
@@ -1972,13 +1979,12 @@ public class DependencyManager<S, T> imp
         return customizer;
     }
 
-    SortedMap<ServiceReference<T>, RefPair<T>> unregisterServiceListener()
+    SortedMap<ServiceReference<T>, RefPair<T>> unregisterServiceListener( AtomicInteger trackingCount )
     {
         SortedMap<ServiceReference<T>, RefPair<T>> refMap;
         ServiceTracker<T, RefPair<T>> tracker = m_tracker;
         if ( tracker != null )
         {
-            AtomicInteger trackingCount = new AtomicInteger( );
             refMap = tracker.close( trackingCount );
             m_tracker = null;
             m_componentManager.log( LogService.LOG_DEBUG, "unregistering service listener for dependency {0}", new Object[]
@@ -1989,6 +1995,7 @@ public class DependencyManager<S, T> imp
             refMap = new TreeMap<ServiceReference<T>, RefPair<T>>(Collections.reverseOrder());
             m_componentManager.log( LogService.LOG_DEBUG, " No existing service listener to unregister for dependency {0}", new Object[]
                     {getName()}, null );
+            trackingCount.set( -1 );
         }
 //        m_registered = false;
         return refMap;

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/EdgeInfo.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/EdgeInfo.java?rev=1523551&r1=1523550&r2=1523551&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/EdgeInfo.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/EdgeInfo.java Mon Sep 16 07:39:24 2013
@@ -20,6 +20,29 @@ package org.apache.felix.scr.impl.manage
 
 import java.util.concurrent.CountDownLatch;
 
+/**
+ * EdgeInfo holds information about the service event tracking counts for creating (open) and disposing (close) 
+ * implementation object instances per dependency manager.  These need to be maintained for each implementation object instance
+ * because each instance (for a service factory) will have different sets of service references available.  These need to be 
+ * maintained for each dependency manager because the open/close tracking counts are obtained when the set of current
+ * service references is obtained, using a lock internal to the service tracker.
+ * 
+ *
+ * The information in the open/close counts is used in the outOfRange method which determines if a service event tracking count 
+ * occurred before the "open" event (in which case it is reflected in the open set already and does not need to be processed separately)
+ * or after the "close" event (in which case it is reflected in the close set already).
+ * 
+ * The open latch is used to make sure that elements in the open set are completely processed before updated or unbind events
+ *  are processed
+ * The close latch is used to make sure that unbind events that are out of range wait for the close to complete before returning; 
+ * in this case the unbind is happening in the "close" thread rather than the service event thread, so we wait for the close to complete 
+ * so that when the service event returns the unbind will actually have been completed.
+ * 
+ * Related to this functionality is the missing tracking in AbstractComponentManager.  This is used on close of an instance to make 
+ * sure all service events occuring before close starts complete processing before the close takes action.
+ *
+ */
+
 class EdgeInfo
 {
     private int open = -1;
@@ -41,6 +64,7 @@ class EdgeInfo
     {
         this.openLatch = latch;
     }
+    
     public CountDownLatch getCloseLatch()
     {
         return closeLatch;

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java?rev=1523551&r1=1523550&r2=1523551&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java Mon Sep 16 07:39:24 2013
@@ -56,7 +56,7 @@ public class ImmediateComponentManager<S
     private volatile ComponentContextImpl<S> m_componentContext;
 
     // the component holder responsible for managing this component
-    private ComponentHolder m_componentHolder;
+    private final ComponentHolder m_componentHolder;
 
     // optional properties provided in the ComponentFactory.newInstance method
     private Dictionary<String, Object> m_factoryProperties;
@@ -167,15 +167,19 @@ public class ImmediateComponentManager<S
         if ( m_componentContext != null )
         {
             m_useCount.set( 0 );
-            m_componentContext.setImplementationAccessible( false );
             disposeImplementationObject( m_componentContext, reason );
             m_componentContext = null;
             log( LogService.LOG_DEBUG, "Unset and deconfigured implementation object for component {0} in deleteComponent for reason {1}", new Object[] { getName(), REASONS[ reason ] },  null );
-            m_properties = null;
-            m_serviceProperties = null;
+            clearServiceProperties();
         }
     }
 
+    void clearServiceProperties()
+    {
+        m_properties = null;
+        m_serviceProperties = null;
+    }
+
 
     public ComponentInstance getComponentInstance()
     {
@@ -324,6 +328,7 @@ public class ImmediateComponentManager<S
     protected void disposeImplementationObject( ComponentContextImpl<S> componentContext,
             int reason )
     {
+        componentContext.setImplementationAccessible( false );
         S implementationObject = componentContext.getImplementationObject( false );
 
         // 1. Call the deactivate method, if present
@@ -566,6 +571,9 @@ public class ImmediateComponentManager<S
             // clear the current properties to force using the configuration data
             m_properties = null;
 
+            
+            //TODO wait for activation/deactivation to complete, then lock(?) or internal disable...
+            
             // unsatisfied component and non-ignored configuration may change targets
             // to satisfy references
             if ( getState() == STATE_UNSATISFIED

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java?rev=1523551&r1=1523550&r2=1523551&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java Mon Sep 16 07:39:24 2013
@@ -88,6 +88,7 @@ public class ServiceFactoryComponentMana
             log( LogService.LOG_DEBUG, "Unset implementation object for component {0} in deleteComponent for reason {1}", new Object[] { getName(), REASONS[ reason ] },  null );
         }
         serviceContexts.clear();
+        clearServiceProperties();
     }