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 2012/10/13 18:15:17 UTC
svn commit: r1397886 - in
/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager:
AbstractComponentManager.java ComponentFactoryImpl.java
DependencyManager.java ImmediateComponentManager.java
Author: djencks
Date: Sat Oct 13 16:15:16 2012
New Revision: 1397886
URL: http://svn.apache.org/viewvc?rev=1397886&view=rev
Log:
FELIX-3680 change target filter safely. Target filter is still set too often and size recomputed when filter does not change
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/ComponentFactoryImpl.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/ImmediateComponentManager.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=1397886&r1=1397885&r2=1397886&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 Sat Oct 13 16:15:16 2012
@@ -1057,6 +1057,15 @@ public abstract class AbstractComponentM
}
}
+ protected void updateTargets(Dictionary properties)
+ {
+ for (Object o: m_dependencyManagers)
+ {
+ DependencyManager dependencyManager = ( DependencyManager ) o;
+ dependencyManager.setTargetFilter( properties );
+ }
+ }
+
protected boolean verifyDependencyManagers( Dictionary properties )
{
// indicates whether all dependencies are satisfied
@@ -1068,7 +1077,7 @@ public abstract class AbstractComponentM
DependencyManager dm = ( DependencyManager ) it.next();
// ensure the target filter is correctly set
- dm.setTargetFilter( properties );
+// dm.setTargetFilter( properties );
if ( !dm.hasGetPermission() )
{
Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java?rev=1397886&r1=1397885&r2=1397886&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java Sat Oct 13 16:15:16 2012
@@ -103,10 +103,11 @@ public class ComponentFactoryImpl extend
try
{
cm.setFactoryProperties( dictionary );
- cm.reconfigure( m_configuration );
-
- // enable and activate immediately
+ // enable
cm.enableInternal();
+ //configure the properties
+ cm.reconfigure( m_configuration );
+ //activate immediately
cm.activateInternal();
instance = cm.getComponentInstance();
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=1397886&r1=1397885&r2=1397886&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 Sat Oct 13 16:15:16 2012
@@ -296,6 +296,7 @@ public class DependencyManager implement
synchronized ( changes )
{
changes.remove( ref );
+ changes.notify();
}
}
if ( release )
@@ -619,49 +620,14 @@ public class DependencyManager implement
*/
void enable() throws InvalidSyntaxException
{
- // setup the target filter from component descriptor
- setTargetFilter( m_dependencyMetadata.getTarget() );
-
if ( hasGetPermission() )
{
- // register the service listener
- String filterString = "(" + Constants.OBJECTCLASS + "=" + m_dependencyMetadata.getInterface() + ")";
- m_componentManager.getActivator().getBundleContext().addServiceListener( this, filterString );
-
- synchronized ( enableLock )
- {
- // get the current number of registered services available
- ServiceReference refs[] = getFrameworkServiceReferences();
- synchronized ( added )
- {
- if (refs != null)
- {
- for (ServiceReference ref: refs)
- {
- added.remove( ref );
- }
- }
- }
- synchronized ( removed )
- {
- if (refs != null)
- {
- for (ServiceReference ref: refs)
- {
- if (!removed.contains( ref ))
- {
- removed.remove( ref );
- }
- }
- }
- }
- m_size.set( ( refs == null ) ? 0 : refs.length);
- }
-
+ // setup the target filter from component descriptor
+ setTargetFilter( m_dependencyMetadata.getTarget() );
m_componentManager.log( LogService.LOG_DEBUG,
- "Registered for service events, currently {0} service(s) match the filter", new Object[]
- { new Integer( m_size.get() ) }, null );
+ "Registered for service events, currently {0} service(s) match the filter", new Object[]
+ {new Integer( m_size.get() )}, null );
}
else
{
@@ -1483,7 +1449,15 @@ public class DependencyManager implement
*/
void setTargetFilter( Dictionary properties )
{
- setTargetFilter( ( String ) properties.get( m_dependencyMetadata.getTargetPropertyName() ) );
+ try
+ {
+ setTargetFilter( ( String ) properties.get( m_dependencyMetadata.getTargetPropertyName() ) );
+ }
+ catch ( InvalidSyntaxException e )
+ {
+ // this should not occur. The only choice would be if the filter for the object class was invalid,
+ // but we already set this once when we enabled.
+ }
}
@@ -1497,85 +1471,134 @@ public class DependencyManager implement
* @param target The new target filter to be set. This may be
* <code>null</code> if no target filtering is to be used.
*/
- private void setTargetFilter( String target )
+ private void setTargetFilter( String target ) throws InvalidSyntaxException
{
m_componentManager.checkLocked();
// do nothing if target filter does not change
if ( ( m_target == null && target == null ) || ( m_target != null && m_target.equals( target ) ) )
{
m_componentManager.log( LogService.LOG_DEBUG, "No change in target property for dependency {0}", new Object[]
- { m_dependencyMetadata.getName() }, null );
- return;
+ {m_dependencyMetadata.getName()}, null );
}
-
- m_target = target;
- if ( target != null )
+ else
{
- m_componentManager.log( LogService.LOG_DEBUG, "Setting target property for dependency {0} to {1}", new Object[]
- { m_dependencyMetadata.getName(), target }, null );
- try
+ m_target = target;
+
+ m_componentManager.getActivator().getBundleContext().removeServiceListener( this );
+ //compute the new target filter while we wait for other threads to complete.
+ if ( target != null )
{
- m_targetFilter = m_componentManager.getActivator().getBundleContext().createFilter( target );
+ m_componentManager.log( LogService.LOG_DEBUG, "Setting target property for dependency {0} to {1}", new Object[]
+ {m_dependencyMetadata.getName(), target}, null );
+ try
+ {
+ m_targetFilter = m_componentManager.getActivator().getBundleContext().createFilter( target );
+ }
+ catch ( InvalidSyntaxException ise )
+ {
+ m_componentManager.log( LogService.LOG_ERROR, "Invalid syntax in target property for dependency {0} to {1}", new Object[]
+ {m_dependencyMetadata.getName(), target}, null );
+ // log
+ m_targetFilter = null;
+ }
}
- catch ( InvalidSyntaxException ise )
+ else
{
- m_componentManager.log( LogService.LOG_ERROR, "Invalid syntax in target property for dependency {0} to {1}", new Object[]
- { m_dependencyMetadata.getName(), target }, null );
- // log
+ m_componentManager.log( LogService.LOG_DEBUG, "Clearing target property for dependency {0}", new Object[]
+ {m_dependencyMetadata.getName()}, null );
m_targetFilter = null;
}
}
- else
+ //wait for events to finish processing
+ synchronized ( added )
{
- m_componentManager.log( LogService.LOG_DEBUG, "Clearing target property for dependency {0}", new Object[]
- { m_dependencyMetadata.getName() }, null );
- m_targetFilter = null;
+ while ( !added.isEmpty() )
+ {
+ try
+ {
+ added.wait();
+ }
+ catch ( InterruptedException e )
+ {
+ //??
+ }
+ }
+ }
+ synchronized ( removed )
+ {
+ while ( !removed.isEmpty() )
+ {
+ try
+ {
+ removed.wait();
+ }
+ catch ( InterruptedException e )
+ {
+ //??
+ }
+ }
}
- if ( m_componentManager.getDependencyMap() != null )
+ //we are now done processing all the events received before we removed the listener.
+ ServiceReference[] boundRefs = getBoundServiceReferences();
+ if ( boundRefs != null && m_targetFilter != null )
{
- //component is active, we need to check what might have changed.
- // check for services to be removed
- if ( m_targetFilter != null )
+ for ( ServiceReference boundRef : boundRefs )
{
- ServiceReference[] refs = getBoundServiceReferences();
- if ( refs != null )
+ if ( !m_targetFilter.match( boundRef ) )
{
- for ( int i = 0; i < refs.length; i++ )
- {
- if ( !m_targetFilter.match( refs[i] ) )
- {
- // might want to do this asynchronously ??
- serviceRemoved( refs[i] );
- }
- }
+ serviceRemoved( boundRef );
}
}
}
+ boolean active = m_componentManager.getDependencyMap() != null;
+ // register the service listener
+ String filterString = "(" + Constants.OBJECTCLASS + "=" + m_dependencyMetadata.getInterface() + ")";
+ m_componentManager.getActivator().getBundleContext().addServiceListener( this, filterString );
+ Collection<ServiceReference> toAdd = new ArrayList<ServiceReference>();
- // check for new services to be added and set the number of
- // matching services
- ServiceReference[] refs = getFrameworkServiceReferences();
- if ( refs != null )
+ synchronized ( enableLock )
{
- if ( m_componentManager.getDependencyMap() != null )
+ // get the current number of registered services available
+ ServiceReference refs[] = getFrameworkServiceReferences();
+ if ( refs != null )
{
- for ( int i = 0; i < refs.length; i++ )
+ synchronized ( added )
+ {
+ for ( ServiceReference ref : refs )
+ {
+ added.remove( ref );
+ }
+ }
+ synchronized ( removed )
{
- if ( getBoundService( refs[i] ) == null )
+ for ( ServiceReference ref : refs )
{
- // might want to do this asynchronously ??
- serviceAdded( refs[i] );
+ if ( !removed.contains( ref ) )
+ {
+ removed.remove( ref );
+ }
+ }
+ }
+ if ( active )
+ {
+ for ( ServiceReference ref : refs )
+ {
+ if ( getBoundService( ref ) == null )
+ {
+ toAdd.add( ref );
+ }
}
}
}
- m_size.set( refs.length );
+ m_size.set( ( refs == null ) ? 0 : refs.length );
}
- else
+
+ for ( ServiceReference ref : toAdd )
{
- // no services currently match the filter
- m_size.set( 0 );
+ serviceAdded( ref );
}
+
}
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=1397886&r1=1397885&r2=1397886&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 Sat Oct 13 16:15:16 2012
@@ -464,6 +464,8 @@ public class ImmediateComponentManager e
// clear the current properties to force using the configuration data
m_properties = null;
+ updateTargets( getProperties() );
+
// unsatisfied component and non-ignored configuration may change targets
// to satisfy references
if ( getState() == STATE_UNSATISFIED && configuration != null