FELIX-1173 Do not run tasks when the component defining bundle is not active any more.
This prevents components from being manipulated while the bundle is already shutting down.

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@778518 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/AbstractComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/AbstractComponentManager.java
index 30ce973..a4789b4 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/AbstractComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/AbstractComponentManager.java
@@ -98,7 +98,7 @@
     {
         getActivator().schedule( new ComponentActivatorTask("Enable", this)
         {
-            public void run()
+            public void doRun()
             {
                 enableInternal();
             }
@@ -144,7 +144,7 @@
         
         getActivator().schedule( new ComponentActivatorTask("Activate", this)
         {
-            public void run()
+            public void doRun()
             {
                 activateInternal();
             }
@@ -175,7 +175,7 @@
     {
         getActivator().schedule( new ComponentActivatorTask( "Reactivate", this )
         {
-            public void run()
+            public void doRun()
             {
                 deactivateInternal();
                 activateInternal();
@@ -216,7 +216,7 @@
         
         getActivator().schedule( new ComponentActivatorTask( "Deactivate", this )
         {
-            public void run()
+            public void doRun()
             {
                 deactivateInternal();
             }
@@ -253,7 +253,7 @@
     {
         getActivator().schedule( new ComponentActivatorTask("Disable", this)
         {
-            public void run()
+            public void doRun()
             {
                 disableInternal();
             }
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
index f501a6a..bfb04eb 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/ComponentActivatorTask.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/ComponentActivatorTask.java
@@ -19,6 +19,10 @@
 package org.apache.felix.scr.impl;
 
 
+import org.osgi.framework.Bundle;
+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()}
@@ -39,6 +43,24 @@
     }
 
 
+    protected abstract void doRun();
+
+
+    public void run()
+    {
+        // fail, if the bundle is not active
+        if ( component.getBundle().getState() == Bundle.ACTIVE )
+        {
+            doRun();
+        }
+        else
+        {
+            Activator.log( LogService.LOG_WARNING, component.getBundle(), "Cannot run task '" + this
+                + "': Providing bundle is not active", null );
+        }
+    }
+
+
     public String toString()
     {
         return taskName + " " + component;
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/ComponentActorThread.java b/scr/src/main/java/org/apache/felix/scr/impl/ComponentActorThread.java
index 7aa20ef..bb88edc 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/ComponentActorThread.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/ComponentActorThread.java
@@ -27,12 +27,24 @@
 /**
  * The <code>ComponentActorThread</code> is the thread used to act upon registered
  * components of the service component runtime.
- *
- * @author fmeschbe
  */
 class ComponentActorThread extends Thread
 {
 
+    // sentinel task to terminate this thread
+    private static final Runnable TERMINATION_TASK = new Runnable()
+    {
+        public void run()
+        {
+        }
+
+
+        public String toString()
+        {
+            return "Component Actor Terminator";
+        }
+    };
+
     // the queue of Runnable instances  to be run
     private LinkedList tasks;
 
@@ -72,7 +84,7 @@
             }
 
             // return if the task is this thread itself
-            if ( task == this )
+            if ( task == TERMINATION_TASK )
             {
                 Activator.log( LogService.LOG_DEBUG, null, "Shutting down ComponentActorThread", null );
                 return;
@@ -96,7 +108,7 @@
     // of the queue
     void terminate()
     {
-        schedule( this );
+        schedule( TERMINATION_TASK );
     }
 
 
@@ -110,7 +122,7 @@
 
             Activator.log( LogService.LOG_DEBUG, null, "Adding task [" + task + "] as #" + tasks.size()
                 + " in the queue", null );
-            
+
             // notify the waiting thread
             tasks.notifyAll();
         }