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();
}