You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by gn...@apache.org on 2009/07/03 16:41:15 UTC
svn commit: r790932 -
/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/BlueprintExtender.java
Author: gnodet
Date: Fri Jul 3 14:41:15 2009
New Revision: 790932
URL: http://svn.apache.org/viewvc?rev=790932&view=rev
Log:
Fix extender shutdown
Modified:
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/BlueprintExtender.java
Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/BlueprintExtender.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/BlueprintExtender.java?rev=790932&r1=790931&r2=790932&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/BlueprintExtender.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/BlueprintExtender.java Fri Jul 3 14:41:15 2009
@@ -24,6 +24,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Comparator;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@@ -37,6 +38,7 @@
import org.osgi.framework.BundleEvent;
import org.osgi.framework.Constants;
import org.osgi.framework.SynchronousBundleListener;
+import org.osgi.framework.ServiceReference;
import org.osgi.service.blueprint.container.BlueprintContainer;
import org.osgi.service.blueprint.container.BlueprintEvent;
import org.slf4j.Logger;
@@ -88,21 +90,58 @@
public void stop(BundleContext context) {
LOGGER.debug("Stopping blueprint extender...");
- // TODO: we should order the blueprint container destruction wrt service exports / dependencies
- // TODO: also if a blueprint bundle is being stopped at the same time (this could happen if the framework
- // TODO: is shut down, we should not wait for the blueprint container to be destroyed if it is already being
- // TODO: destroyed by the extender
- List<Bundle> bundles = new ArrayList<Bundle>(containers.keySet());
- for (Bundle bundle : bundles) {
+ context.removeBundleListener(this);
+ // Orderly shutdown of containers
+ while (!containers.isEmpty()) {
+ Bundle bundle = getBundleToDestroy();
destroyContext(bundle);
}
- context.removeBundleListener(this);
this.eventDispatcher.destroy();
this.handlers.destroy();
executors.shutdown();
LOGGER.debug("Blueprint extender stopped");
}
+ private Bundle getBundleToDestroy() {
+ Bundle bundleToDestroy = null;
+ for (Bundle bundle : containers.keySet()) {
+ ServiceReference[] references = bundle.getRegisteredServices();
+ int usage = 0;
+ if (references != null) {
+ for (ServiceReference reference : references) {
+ Bundle[] usingBundles = reference.getUsingBundles();
+ if (usingBundles != null) {
+ usage += usingBundles.length;
+ }
+ }
+ }
+ LOGGER.debug("Usage for bundle {} is {}", bundle, usage);
+ if (usage == 0) {
+ if (bundleToDestroy == null) {
+ LOGGER.debug("Currently selecting bundle {} for destroy (first bundle with no usage)", bundle);
+ bundleToDestroy = bundle;
+ } else if (bundle.getLastModified() > bundleToDestroy.getLastModified()) {
+ LOGGER.debug("Currently selecting bundle {} for destroy (it has been installed more recently)", bundle);
+ bundleToDestroy = bundle;
+ }
+ }
+ }
+ if (bundleToDestroy == null) {
+ ServiceReference ref = null;
+ for (Bundle bundle : containers.keySet()) {
+ ServiceReference[] references = bundle.getRegisteredServices();
+ for (ServiceReference reference : references) {
+ if (ref == null || reference.compareTo(ref) > 0) {
+ LOGGER.debug("Currently selecting bundle {} for destroy (with reference {})", bundle, reference);
+ ref = reference;
+ }
+ }
+ }
+ bundleToDestroy = ref.getBundle();
+ }
+ return bundleToDestroy;
+ }
+
public void bundleChanged(BundleEvent event) {
Bundle bundle = event.getBundle();
if (event.getType() == BundleEvent.LAZY_ACTIVATION) {