FELIX-2368 make component enablement, activation, deactivation, and disablement synchronous instead of asynchronous
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@949317 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java b/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java
index 2d6df6a..31de35e 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java
@@ -384,7 +384,7 @@
* @param name The name of the component to enable or <code>null</code> to
* enable all components.
*/
- public void enableComponent( String name )
+ public void enableComponent( final String name )
{
final ComponentHolder[] holder = getSelectedComponents( name );
if ( holder == null )
@@ -392,17 +392,35 @@
return;
}
- for ( int i = 0; i < holder.length; i++ )
+ // FELIX-2368; schedule for asynchronous enablement. According to
+ // 112.5.1 the enabled state should be changed immediately but
+ // the component(s) should be activated asynchronously. Since
+ // we do not really handle the enabled state separately we
+ // schedule enablement and activation for asynchronous execution.
+ schedule( new Runnable()
{
- try
+ public void run()
{
- holder[i].enableComponents();
+ for ( int i = 0; i < holder.length; i++ )
+ {
+ try
+ {
+ log( LogService.LOG_DEBUG, "Enabling Component", holder[i].getComponentMetadata(), null );
+ holder[i].enableComponents();
+ }
+ catch ( Throwable t )
+ {
+ log( LogService.LOG_ERROR, "Cannot enable component", holder[i].getComponentMetadata(), t );
+ }
+ }
}
- catch ( Throwable t )
+
+
+ public String toString()
{
- log( LogService.LOG_ERROR, "Cannot enable component", holder[i].getComponentMetadata(), t );
+ return "enableComponent(" + name + ")";
}
- }
+ } );
}
@@ -417,7 +435,7 @@
* @param name The name of the component to disable or <code>null</code> to
* disable all components.
*/
- public void disableComponent( String name )
+ public void disableComponent( final String name )
{
final ComponentHolder[] holder = getSelectedComponents( name );
if ( holder == null )
@@ -425,18 +443,35 @@
return;
}
- for ( int i = 0; i < holder.length; i++ )
+ // FELIX-2368; schedule for asynchronous enablement. According to
+ // 112.5.1 the enabled state should be changed immediately but
+ // the component(s) should be deactivated asynchronously. Since
+ // we do not really handle the enabled state separately we
+ // schedule disablement and deactivation for asynchronous execution.
+ schedule( new Runnable()
{
- try
+ public void run()
{
- log( LogService.LOG_DEBUG, "Disabling Component", holder[i].getComponentMetadata(), null );
- holder[i].disableComponents();
+ for ( int i = 0; i < holder.length; i++ )
+ {
+ try
+ {
+ log( LogService.LOG_DEBUG, "Disabling Component", holder[i].getComponentMetadata(), null );
+ holder[i].disableComponents();
+ }
+ catch ( Throwable t )
+ {
+ log( LogService.LOG_ERROR, "Cannot disable component", holder[i].getComponentMetadata(), t );
+ }
+ }
}
- catch ( Throwable t )
+
+
+ public String toString()
{
- log( LogService.LOG_ERROR, "Cannot disable component", holder[i].getComponentMetadata(), t );
+ return "disableComponent(" + name + ")";
}
- }
+ } );
}
@@ -502,7 +537,7 @@
*
* @param task The component task to execute
*/
- public void schedule( ComponentActivatorTask task )
+ public void schedule( Runnable task )
{
if ( isActive() )
{
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/ComponentActivatorTask.java b/scr/src/main/java/org/apache/felix/scr/impl/ComponentActivatorTask.java
deleted file mode 100644
index 25ec938..0000000
--- a/scr/src/main/java/org/apache/felix/scr/impl/ComponentActivatorTask.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.scr.impl;
-
-
-import org.apache.felix.scr.Component;
-import org.apache.felix.scr.impl.manager.AbstractComponentManager;
-import org.osgi.service.log.LogService;
-
-
-/**
- * The <code>ComponentActivatorTask</code> extends the <code>Runnable</code>
- * interface with the functionality to have a meaningful {@link #toString()}
- * implementation. This is mainly used when logging something around the task
- * being run or scheduled.
- */
-public abstract class ComponentActivatorTask implements Runnable
-{
-
- private final String taskName;
- private final AbstractComponentManager component;
-
-
- protected ComponentActivatorTask( String taskName, AbstractComponentManager component )
- {
- this.taskName = taskName;
- this.component = component;
- }
-
-
- protected abstract void doRun();
-
-
- public void run()
- {
- // fail, if the bundle is not active
- if ( component.getState() == Component.STATE_DISPOSED )
- {
- // cannot use bundle to log because it is not accessible from the
- // component if the component is destroyed
- Activator.log( LogService.LOG_WARNING, null, "Cannot run task '" + this
- + "': Component has already been disposed", null );
- }
- else if ( !ComponentRegistry.isBundleActive( component.getBundle() ) )
- {
- Activator.log( LogService.LOG_WARNING, component.getBundle(), "Cannot run task '" + this
- + "': Declaring bundle is not active", null );
- }
- else
- {
- doRun();
- }
- }
-
-
- public String toString()
- {
- return taskName + " " + component;
- }
-}
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 bab62cf..3a33e50 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
@@ -30,7 +30,6 @@
import org.apache.felix.scr.Component;
import org.apache.felix.scr.Reference;
import org.apache.felix.scr.impl.BundleComponentActivator;
-import org.apache.felix.scr.impl.ComponentActivatorTask;
import org.apache.felix.scr.impl.metadata.ComponentMetadata;
import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
import org.apache.felix.scr.impl.metadata.ServiceMetadata;
@@ -126,37 +125,24 @@
* This method ignores the <i>enabled</i> flag of the component metadata
* and just enables as requested.
* <p>
- * This method schedules the enablement for asynchronous execution.
+ * This method enables and activates the component immediately.
*/
public final void enable()
{
enableInternal();
-
- getActivator().schedule( new ComponentActivatorTask( "Enable", this )
- {
- public void doRun()
- {
- activateInternal();
- }
- });
+ activateInternal();
}
/**
* Disables this component and - if active - first deactivates it. The
* component may be reenabled by calling the {@link #enable()} method.
* <p>
- * This method schedules the disablement for asynchronous execution.
+ * This method deactivates and disables the component immediately.
*/
public final void disable()
{
- getActivator().schedule( new ComponentActivatorTask( "Disable", this )
- {
- public void doRun()
- {
- deactivateInternal( ComponentConstants.DEACTIVATION_REASON_DISABLED );
- disableInternal();
- }
- });
+ deactivateInternal( ComponentConstants.DEACTIVATION_REASON_DISABLED );
+ disableInternal();
}
/**
@@ -522,42 +508,6 @@
}
}
- /**
- * Activates this component if satisfied. If any of the dependencies is
- * not met, the component is not activated and remains unsatisfied.
- * <p>
- * This method schedules the activation for asynchronous execution.
- */
- public final void activate()
- {
- getActivator().schedule( new ComponentActivatorTask( "Activate", this ) {
- public void doRun()
- {
- activateInternal();
- }
- });
- }
-
- /**
- * Cycles this component by deactivating it and - if still satisfied -
- * activating it again asynchronously.
- * <p>
- * This method schedules the deactivation and reactivation for asynchronous
- * execution.
- */
- public final void reactivate( final int reason )
- {
- getActivator().schedule( new ComponentActivatorTask( "Reactivate", this )
- {
-
- public void doRun()
- {
- deactivateInternal( reason );
- activateInternal();
- }
- } );
- }
-
public String toString()
{
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 54c9b79..69290d4 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
@@ -203,7 +203,8 @@
"Dependency Manager: Service {0} registered, activate component", new Object[]
{ m_dependencyMetadata.getName() }, null );
- m_componentManager.activate();
+ // immediately try to activate the component (FELIX-2368)
+ m_componentManager.activateInternal();
}
}
else if ( isMultiple() )
@@ -278,7 +279,8 @@
"Dependency Manager: Service {0} registered, activate component", new Object[]
{ m_dependencyMetadata.getName() }, null );
- m_componentManager.activate();
+ // immediately try to activate the component (FELIX-2368)
+ m_componentManager.activateInternal();
}
// otherwise check whether the component is in a state to handle the event
@@ -365,7 +367,8 @@
"Dependency Manager: Static dependency on {0}/{1} is broken", new Object[]
{ m_dependencyMetadata.getName(), m_dependencyMetadata.getInterface() }, null );
m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE );
- m_componentManager.activate();
+ // FELIX-2368: immediately try to reactivate
+ m_componentManager.activateInternal();
}
catch ( Exception ex )
{
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
index e6cd76b..68ec203 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
@@ -404,7 +404,12 @@
log( LogService.LOG_DEBUG, "Deactivating and Activating to reconfigure from configuration", null );
int reason = ( configuration == null ) ? ComponentConstants.DEACTIVATION_REASON_CONFIGURATION_DELETED
: ComponentConstants.DEACTIVATION_REASON_CONFIGURATION_MODIFIED;
- reactivate( reason );
+
+ // FELIX-2368: cycle component immediately, reconfigure() is
+ // called through ConfigurationListener API which itself is
+ // called asynchronously by the Configuration Admin Service
+ deactivateInternal( reason );
+ activateInternal();
}
}