FELIX-2557 Further work on event dispatching: ConfigurationManager now uses two separate threads to dispatch configuration events and configuration updates. Both threads are configured to be members of their own thread group, which is a daemon group to be destroyed once both dispatcher threads terminate.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@989533 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java b/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java
index 860dbc5..52abff7 100644
--- a/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java
+++ b/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java
@@ -122,6 +122,9 @@
// the thread used to schedule tasks required to run asynchronously
private UpdateThread updateThread;
+ // the thread used to schedule events to be dispatched asynchronously
+ private UpdateThread eventThread;
+
/**
* The actual list of {@link PersistenceManager persistence managers} to use
* when looking for configuration data. This list is built from the
@@ -192,8 +195,10 @@
configurationListenerTracker.open();
// initialize the asynchonous updater thread
- this.updateThread = new UpdateThread( this );
- this.updateThread.start();
+ ThreadGroup tg = new ThreadGroup( "Configuration Admin Service" );
+ tg.setDaemon( true );
+ this.updateThread = new UpdateThread( this, tg, "CM Configuration Updater" );
+ this.eventThread = new UpdateThread( this, tg, "CM Event Dispatcher" );
// set up the location (might throw IllegalArgumentException)
try
@@ -275,18 +280,12 @@
if ( updateThread != null )
{
- // terminate asynchrounous updates
updateThread.terminate();
+ }
- // wait for all updates to terminate
- try
- {
- updateThread.join();
- }
- catch ( InterruptedException ie )
- {
- // don't really care
- }
+ if ( eventThread != null )
+ {
+ eventThread.terminate();
}
if ( logTracker != null )
@@ -590,7 +589,7 @@
FireConfigurationEvent event = new FireConfigurationEvent( type, pid, factoryPid );
if ( event.hasConfigurationEventListeners() )
{
- updateThread.schedule( event );
+ eventThread.schedule( event );
}
else if ( isLogEnabled( LogService.LOG_DEBUG ) )
{
diff --git a/configadmin/src/main/java/org/apache/felix/cm/impl/UpdateThread.java b/configadmin/src/main/java/org/apache/felix/cm/impl/UpdateThread.java
index 562036b..f68cc6c 100644
--- a/configadmin/src/main/java/org/apache/felix/cm/impl/UpdateThread.java
+++ b/configadmin/src/main/java/org/apache/felix/cm/impl/UpdateThread.java
@@ -28,27 +28,32 @@
* The <code>UpdateThread</code> is the thread used to update managed services
* and managed service factories as well as to send configuration events.
*/
-public class UpdateThread extends Thread
+public class UpdateThread implements Runnable
{
- // the base name of the thread which is set while there is no
- // task to run
- private static final String BASE_THREAD_NAME = "Configuration Updater";
-
// the configuration manager on whose behalf this thread is started
// (this is mainly used for logging)
- private ConfigurationManager configurationManager;
+ private final ConfigurationManager configurationManager;
+
+ // the thread's base name
+ private final String workerBaseName;
// the queue of Runnable instances to be run
- private LinkedList updateTasks;
+ private final LinkedList updateTasks;
+
+ // the actual thread
+ private final Thread worker;
- public UpdateThread( ConfigurationManager configurationManager )
+ public UpdateThread( final ConfigurationManager configurationManager, final ThreadGroup tg, final String name )
{
- super( BASE_THREAD_NAME );
-
this.configurationManager = configurationManager;
+ this.workerBaseName = name;
+
this.updateTasks = new LinkedList();
+ this.worker = new Thread( tg, this, name );
+ this.worker.setDaemon( true );
+ this.worker.start();
}
@@ -89,7 +94,7 @@
try
{
// set the thread name indicating the current task
- setName( BASE_THREAD_NAME + " (" + task + ")" );
+ worker.setName( workerBaseName + " (" + task + ")" );
if ( configurationManager.isLogEnabled( LogService.LOG_DEBUG ) )
{
@@ -105,17 +110,27 @@
finally
{
// reset the thread name to "idle"
- setName( BASE_THREAD_NAME );
+ worker.setName( workerBaseName );
}
}
}
// cause this thread to terminate by adding this thread to the end
- // of the queue
+ // of the queue and wait for the thread to actually terminate
void terminate()
{
schedule( this );
+
+ // wait for all updates to terminate
+ try
+ {
+ worker.join();
+ }
+ catch ( InterruptedException ie )
+ {
+ // don't really care
+ }
}