Applied patch (FELIX-170) to stop the start level and package admin threads
when the framework shuts down.
git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@472013 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/PackageAdminActivator.java b/framework/src/main/java/org/apache/felix/framework/PackageAdminActivator.java
index ec78129..5e9175e 100644
--- a/framework/src/main/java/org/apache/felix/framework/PackageAdminActivator.java
+++ b/framework/src/main/java/org/apache/felix/framework/PackageAdminActivator.java
@@ -24,6 +24,7 @@
{
private Felix m_felix = null;
private ServiceRegistration m_reg = null;
+ private PackageAdminImpl m_packageAdmin = null;
public PackageAdminActivator(Felix felix)
{
@@ -32,13 +33,15 @@
public void start(BundleContext context) throws Exception
{
+ m_packageAdmin = new PackageAdminImpl(m_felix);
m_reg = context.registerService(
org.osgi.service.packageadmin.PackageAdmin.class.getName(),
- new PackageAdminImpl(m_felix), null);
+ m_packageAdmin, null);
}
public void stop(BundleContext context) throws Exception
{
m_reg.unregister();
+ m_packageAdmin.stop();
}
}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java b/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
index 9c6a6f6..56148c3 100644
--- a/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
@@ -29,6 +29,7 @@
private Felix m_felix = null;
private Bundle[][] m_reqBundles = null;
private Bundle m_systemBundle = null;
+ private Thread m_thread = null;
public PackageAdminImpl(Felix felix)
{
@@ -36,12 +37,35 @@
m_systemBundle = m_felix.getBundle(0);
// Start a thread to perform asynchronous package refreshes.
- Thread t = new Thread(this, "FelixPackageAdmin");
- t.setDaemon(true);
- t.start();
+ m_thread = new Thread(this, "FelixPackageAdmin");
+ m_thread.setDaemon(true);
+ m_thread.start();
}
/**
+ * Stops the FelixPackageAdmin thread on system shutdown. Shutting down the
+ * thread explicitly is required in the embedded case, where Felix may be
+ * stopped without the Java VM being stopped. In this case the
+ * FelixPackageAdmin thread must be stopped explicitly.
+ * <p>
+ * This method is called by the
+ * {@link PackageAdminActivator#stop(BundleContext)} method.
+ */
+ synchronized void stop()
+ {
+ if (m_thread != null)
+ {
+ // Null thread variable to signal to the thread that
+ // we want it to exit.
+ m_thread = null;
+
+ // Wake up the thread, if it is currently in the wait() state
+ // for more work.
+ notifyAll();
+ }
+ }
+
+ /**
* Returns the bundle associated with this class if the class was
* loaded from a bundle, otherwise returns null.
*
@@ -210,6 +234,12 @@
// Wait for a refresh request.
while (m_reqBundles == null)
{
+ // Terminate the thread if requested to do so (see stop()).
+ if (m_thread == null)
+ {
+ return;
+ }
+
try
{
wait();
diff --git a/framework/src/main/java/org/apache/felix/framework/StartLevelActivator.java b/framework/src/main/java/org/apache/felix/framework/StartLevelActivator.java
index 20b7970..61e8046 100644
--- a/framework/src/main/java/org/apache/felix/framework/StartLevelActivator.java
+++ b/framework/src/main/java/org/apache/felix/framework/StartLevelActivator.java
@@ -23,6 +23,7 @@
class StartLevelActivator implements BundleActivator
{
private Felix m_felix = null;
+ private StartLevelImpl m_startLevel = null;
private ServiceRegistration m_reg = null;
public StartLevelActivator(Felix felix)
@@ -32,13 +33,15 @@
public void start(BundleContext context) throws Exception
{
+ m_startLevel = new StartLevelImpl(m_felix);
m_reg = context.registerService(
org.osgi.service.startlevel.StartLevel.class.getName(),
- new StartLevelImpl(m_felix), null);
+ m_startLevel, null);
}
public void stop(BundleContext context) throws Exception
{
m_reg.unregister();
+ m_startLevel.stop();
}
}
diff --git a/framework/src/main/java/org/apache/felix/framework/StartLevelImpl.java b/framework/src/main/java/org/apache/felix/framework/StartLevelImpl.java
index ad6d7cd..5be90ff 100644
--- a/framework/src/main/java/org/apache/felix/framework/StartLevelImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/StartLevelImpl.java
@@ -39,16 +39,43 @@
private Felix m_felix = null;
private List m_requestList = null;
private Bundle m_systemBundle = null;
-
+ private Thread m_thread = null;
+
public StartLevelImpl(Felix felix)
{
m_felix = felix;
m_requestList = new ArrayList();
m_systemBundle = m_felix.getBundle(0);
// Start a thread to perform asynchronous package refreshes.
- Thread t = new Thread(this, "FelixStartLevel");
- t.setDaemon(true);
- t.start();
+ m_thread = new Thread(this, "FelixStartLevel");
+ m_thread.setDaemon(true);
+ m_thread.start();
+ }
+
+ /**
+ * Stops the FelixStartLevel thread on system shutdown. Shutting down the
+ * thread explicitly is required in the embedded case, where Felix may be
+ * stopped without the Java VM being stopped. In this case the
+ * FelixStartLevel thread must be stopped explicitly.
+ * <p>
+ * This method is called by the
+ * {@link StartLevelActivator#stop(BundleContext)} method.
+ */
+ void stop()
+ {
+ synchronized (m_requestList)
+ {
+ if (m_thread != null)
+ {
+ // Null thread variable to signal to the thread that
+ // we want it to exit.
+ m_thread = null;
+
+ // Wake up the thread, if it is currently in the wait() state
+ // for more work.
+ m_requestList.notifyAll();
+ }
+ }
}
/* (non-Javadoc)
@@ -199,6 +226,12 @@
// Wait for a request.
while (m_requestList.size() == 0)
{
+ // Terminate the thread if requested to do so (see stop()).
+ if (m_thread == null)
+ {
+ return;
+ }
+
try
{
m_requestList.wait();