diff options
author | Thomas Watson | 2016-03-08 17:33:36 +0000 |
---|---|---|
committer | Thomas Watson | 2016-03-08 17:33:36 +0000 |
commit | 1ae5c93eb0e0c741f3f7831bce8f3b5a906eeb02 (patch) | |
tree | f08e3a96402fd4aac750c28661be4bb73931baad | |
parent | d2e12471494d0dd3721261510cff0b5b4d391754 (diff) | |
download | rt.equinox.framework-1ae5c93eb0e0c741f3f7831bce8f3b5a906eeb02.tar.gz rt.equinox.framework-1ae5c93eb0e0c741f3f7831bce8f3b5a906eeb02.tar.xz rt.equinox.framework-1ae5c93eb0e0c741f3f7831bce8f3b5a906eeb02.zip |
Bug 489233 - Avoid queue start-level operation if a bundle is notY20160310-0830Y20160310-0800
persistently marked for activation
Change-Id: I90372ece802642b0994ee091b73155e425e2bc3e
Signed-off-by: Thomas Watson <tjwatson@us.ibm.com>
2 files changed, 43 insertions, 10 deletions
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/TestModuleContainer.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/TestModuleContainer.java index 33b33ddd9..dc65907c6 100644 --- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/TestModuleContainer.java +++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/TestModuleContainer.java @@ -2539,6 +2539,33 @@ public class TestModuleContainer extends AbstractTest { } @Test + public void testStartLevelDeadlock() throws BundleException, IOException, InterruptedException { + DummyContainerAdaptor adaptor = createDummyAdaptor(); + ModuleContainer container = adaptor.getContainer(); + container.getFrameworkStartLevel().setInitialBundleStartLevel(2); + + // install the system.bundle + Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, Constants.SYSTEM_BUNDLE_SYMBOLICNAME, null, null, container); + ResolutionReport report = container.resolve(Arrays.asList(systemBundle), true); + Assert.assertNull("Failed to resolve system.bundle.", report.getResolutionException()); + systemBundle.start(); + + // install a module + Map<String, String> manifest = new HashMap<String, String>(); + manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2"); + manifest.put(Constants.BUNDLE_SYMBOLICNAME, "module.test"); + Module module = installDummyModule(manifest, manifest.get(Constants.BUNDLE_SYMBOLICNAME), container); + adaptor.setSlowdownEvents(true); + module.setStartLevel(1); + module.start(); + + List<DummyContainerEvent> events = adaptor.getDatabase().getContainerEvents(); + for (DummyContainerEvent event : events) { + Assert.assertNotEquals("Found an error: " + event.error, ContainerEvent.ERROR, event.type); + } + } + + @Test public void testSystemBundleOnDemandFragments() throws BundleException, IOException { DummyContainerAdaptor adaptor = createDummyAdaptor(); ModuleContainer container = adaptor.getContainer(); diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleContainer.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleContainer.java index 00c40a0c8..9470dceb9 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleContainer.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleContainer.java @@ -1448,19 +1448,25 @@ public final class ModuleContainer implements DebugOptionsListener { if (startlevel < 1) { throw new IllegalArgumentException(Msg.ModuleContainer_NegativeStartLevelError + startlevel); } - if (module.getStartLevel() == startlevel) { + int currentLevel = module.getStartLevel(); + if (currentLevel == startlevel) { return; // do nothing } moduleDatabase.setStartLevel(module, startlevel); - // queue start level operation in the background - // notice that we only do one start level operation at a time - CopyOnWriteIdentityMap<Module, FrameworkListener[]> dispatchListeners = new CopyOnWriteIdentityMap<Module, FrameworkListener[]>(); - dispatchListeners.put(module, new FrameworkListener[0]); - ListenerQueue<Module, FrameworkListener[], Integer> queue = new ListenerQueue<Module, FrameworkListener[], Integer>(getManager()); - queue.queueListeners(dispatchListeners.entrySet(), this); - - // dispatch the start level job - queue.dispatchEventAsynchronous(MODULE_STARTLEVEL, startlevel); + // only queue the start level if + // 1) the current level is less than the new startlevel, may need to stop or + // 2) the module is marked for persistent activation, may need to start + if (currentLevel < startlevel || module.isPersistentlyStarted()) { + // queue start level operation in the background + // notice that we only do one start level operation at a time + CopyOnWriteIdentityMap<Module, FrameworkListener[]> dispatchListeners = new CopyOnWriteIdentityMap<Module, FrameworkListener[]>(); + dispatchListeners.put(module, new FrameworkListener[0]); + ListenerQueue<Module, FrameworkListener[], Integer> queue = new ListenerQueue<Module, FrameworkListener[], Integer>(getManager()); + queue.queueListeners(dispatchListeners.entrySet(), this); + + // dispatch the start level job + queue.dispatchEventAsynchronous(MODULE_STARTLEVEL, startlevel); + } } @Override |