Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2016-03-08 17:33:36 +0000
committerThomas Watson2016-03-08 17:33:36 +0000
commit1ae5c93eb0e0c741f3f7831bce8f3b5a906eeb02 (patch)
treef08e3a96402fd4aac750c28661be4bb73931baad /bundles
parentd2e12471494d0dd3721261510cff0b5b4d391754 (diff)
downloadrt.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>
Diffstat (limited to 'bundles')
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/TestModuleContainer.java27
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleContainer.java26
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

Back to the top