diff options
author | Thomas Watson | 2019-06-06 18:11:38 +0000 |
---|---|---|
committer | Thomas Watson | 2019-06-10 13:42:42 +0000 |
commit | ea9b6a9a5eb69d9428a5cf9ea337541a009f4751 (patch) | |
tree | d99d9dfaf49409add7e9f172afa53dbf120c55a9 /bundles/org.eclipse.osgi | |
parent | 7e858cf2d9b52934e943b584b0975eeda8e27fb3 (diff) | |
download | rt.equinox.framework-ea9b6a9a5eb69d9428a5cf9ea337541a009f4751.tar.gz rt.equinox.framework-ea9b6a9a5eb69d9428a5cf9ea337541a009f4751.tar.xz rt.equinox.framework-ea9b6a9a5eb69d9428a5cf9ea337541a009f4751.zip |
Bug 548075 - Ability to control if bundles are activated in parallelI20190610-1800
Add a new option equinox.start.level.restrict.parallel
which is false by default. Setting this value to true
requires that the method Module.setParallelActivation must
be called with true to enable parallel activation for the
Module.
The parallel activation setting is persistent across restarts. Tests
have been added to test for persistence of the setting and that the
setting is applied correctly when activating bundles from the
start-level implementation.
Change-Id: I20ea5807edfd10762fc5758317d946946299d5a7
Signed-off-by: Thomas Watson <tjwatson@us.ibm.com>
Diffstat (limited to 'bundles/org.eclipse.osgi')
6 files changed, 74 insertions, 18 deletions
diff --git a/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF index fc081bfdb..768511155 100644 --- a/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Export-Package: org.eclipse.core.runtime.adaptor;x-friends:="org.eclipse.core.runtime", org.eclipse.core.runtime.internal.adaptor;x-internal:=true, org.eclipse.equinox.log;version="1.1";uses:="org.osgi.framework,org.osgi.service.log", - org.eclipse.osgi.container;version="1.4"; + org.eclipse.osgi.container;version="1.5"; uses:="org.eclipse.osgi.report.resolution, org.osgi.framework.wiring, org.osgi.framework.startlevel, @@ -101,7 +101,7 @@ Bundle-Activator: org.eclipse.osgi.internal.framework.SystemBundleActivator Bundle-Description: %systemBundle Bundle-Copyright: %copyright Bundle-Vendor: %eclipse.org -Bundle-Version: 3.14.100.qualifier +Bundle-Version: 3.15.0.qualifier Bundle-Localization: systembundle Bundle-DocUrl: http://www.eclipse.org Eclipse-ExtensibleAPI: true diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/Module.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/Module.java index 3d6cfbf5b..4a8d7e723 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/Module.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/Module.java @@ -151,7 +151,12 @@ public abstract class Module implements BundleReference, BundleStartLevel, Compa /** * The module has been set to use its activation policy. */ - USE_ACTIVATION_POLICY + USE_ACTIVATION_POLICY, + /** + * The module has been set for parallel activation from start-level + * @since 3.15 + */ + PARALLEL_ACTIVATION } /** @@ -693,11 +698,37 @@ public abstract class Module implements BundleReference, BundleStartLevel, Compa private void persistStopOptions(StopOptions... options) { if (StopOptions.TRANSIENT.isContained(options)) return; - settings.clear(); + settings.remove(Settings.USE_ACTIVATION_POLICY); + settings.remove(Settings.AUTO_START); + revisions.getContainer().moduleDatabase.persistSettings(settings, this); + } + + /** + * Set if this module should be activated in parallel with other modules that have + * the same {@link #getStartLevel() start level}. + * @param parallelActivation true if the module should be started in parallel; false otherwise + * @since 3.15 + */ + public void setParallelActivation(boolean parallelActivation) { + if (parallelActivation) { + settings.add(Settings.PARALLEL_ACTIVATION); + } else { + settings.remove(Settings.PARALLEL_ACTIVATION); + } revisions.getContainer().moduleDatabase.persistSettings(settings, this); } /** + * Returns if this module should be activated in parallel with other modules that have + * the same {@link #getStartLevel() start level}. + * @return true if the module should be started in parallel; false otherwise + * @since 3.15 + */ + public boolean isParallelActivated() { + return settings.contains(Settings.PARALLEL_ACTIVATION); + } + + /** * The container is done with the revision and it has been completely removed. * This method allows the resources behind the revision to be cleaned up. * @param revision the revision to clean up 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 319b21f5d..c248ff4e2 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 @@ -131,6 +131,8 @@ public final class ModuleContainer implements DebugOptionsListener { private final boolean autoStartOnResolve; + final boolean restrictParallelStart; + boolean DEBUG_MONITOR_LAZY = false; boolean DEBUG_BUNDLE_START_TIME = false; @@ -169,6 +171,7 @@ public final class ModuleContainer implements DebugOptionsListener { autoStartOnResolveProp = Boolean.toString(true); } this.autoStartOnResolve = Boolean.parseBoolean(autoStartOnResolveProp); + this.restrictParallelStart = Boolean.parseBoolean(adaptor.getProperty(EquinoxConfiguration.PROP_EQUINOX_START_LEVEL_RESTRICT_PARALLEL)); } /** @@ -1713,7 +1716,9 @@ public final class ModuleContainer implements DebugOptionsListener { long currentTimestamp = Long.MIN_VALUE; if (newStartLevel > currentSL) { List<Module> lazyStart = null; + List<Module> lazyStartParallel = null; List<Module> eagerStart = null; + List<Module> eagerStartParallel = null; for (int i = currentSL; i < newStartLevel; i++) { int toStartLevel = i + 1; activeStartLevel.set(toStartLevel); @@ -1725,14 +1730,16 @@ public final class ModuleContainer implements DebugOptionsListener { try { sorted = moduleDatabase.getSortedModules(Sort.BY_START_LEVEL); lazyStart = new ArrayList<>(sorted.size()); + lazyStartParallel = new ArrayList<>(sorted.size()); eagerStart = new ArrayList<>(sorted.size()); - separateModulesByActivationPolicy(sorted, lazyStart, eagerStart); + eagerStartParallel = new ArrayList<>(sorted.size()); + separateModulesByActivationPolicy(sorted, lazyStart, lazyStartParallel, eagerStart, eagerStartParallel); currentTimestamp = moduleDatabase.getTimestamp(); } finally { moduleDatabase.readUnlock(); } } - incStartLevel(toStartLevel, lazyStart, eagerStart); + incStartLevel(toStartLevel, lazyStart, lazyStartParallel, eagerStart, eagerStartParallel); } } else { for (int i = currentSL; i > newStartLevel; i--) { @@ -1765,26 +1772,38 @@ public final class ModuleContainer implements DebugOptionsListener { } } - private void incStartLevel(int toStartLevel, List<Module> lazyStart, List<Module> eagerStart) { - incStartLevel(toStartLevel, lazyStart); - incStartLevel(toStartLevel, eagerStart); + private void incStartLevel(int toStartLevel, List<Module> lazyStart, List<Module> lazyStartParallel, List<Module> eagerStart, List<Module> eagerStartParallel) { + // start lazy activated first + // start parallel bundles first + incStartLevel(toStartLevel, lazyStartParallel, true); + incStartLevel(toStartLevel, lazyStart, false); + incStartLevel(toStartLevel, eagerStartParallel, true); + incStartLevel(toStartLevel, eagerStart, false); } - private void separateModulesByActivationPolicy(List<Module> sortedModules, List<Module> lazyStart, List<Module> eagerStart) { + private void separateModulesByActivationPolicy(List<Module> sortedModules, List<Module> lazyStart, List<Module> lazyStartParallel, List<Module> eagerStart, List<Module> eagerStartParallel) { for (Module module : sortedModules) { - if (module.isLazyActivate()) { - lazyStart.add(module); + if (!restrictParallelStart || module.isParallelActivated()) { + if (module.isLazyActivate()) { + lazyStartParallel.add(module); + } else { + eagerStartParallel.add(module); + } } else { - eagerStart.add(module); + if (module.isLazyActivate()) { + lazyStart.add(module); + } else { + eagerStart.add(module); + } } } } - private void incStartLevel(final int toStartLevel, List<Module> candidatesToStart) { + private void incStartLevel(final int toStartLevel, List<Module> candidatesToStart, boolean inParallel) { if (candidatesToStart.isEmpty()) { return; } - List<Module> toStart = new ArrayList<>(); + final List<Module> toStart = new ArrayList<>(); for (final Module module : candidatesToStart) { if (isRefreshingSystemModule()) { return; @@ -1807,7 +1826,12 @@ public final class ModuleContainer implements DebugOptionsListener { if (toStart.isEmpty()) { return; } - final Executor executor = adaptor.getStartLevelExecutor(); + final Executor executor = inParallel ? adaptor.getStartLevelExecutor() : new Executor() { + @Override + public void execute(Runnable command) { + command.run(); + } + }; final CountDownLatch done = new CountDownLatch(toStart.size()); for (final Module module : toStart) { executor.execute(new Runnable() { diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleDatabase.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleDatabase.java index 6d7cfc4f5..a25ed24f1 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleDatabase.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleDatabase.java @@ -957,7 +957,7 @@ public class ModuleDatabase { } private static class Persistence { - private static final int VERSION = 2; + private static final int VERSION = 3; private static final byte NULL = 0; private static final byte OBJECT = 1; private static final byte INDEX = 2; diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxConfiguration.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxConfiguration.java index cdf363c88..a6f8da3a6 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxConfiguration.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxConfiguration.java @@ -227,6 +227,7 @@ public class EquinoxConfiguration implements EnvironmentInfo { public static final String PROP_RESOLVER_THREAD_COUNT = "equinox.resolver.thead.count"; //$NON-NLS-1$ public static final String PROP_EQUINOX_RESOLVER_THREAD_COUNT = "equinox.resolver.thread.count"; //$NON-NLS-1$ public static final String PROP_EQUINOX_START_LEVEL_THREAD_COUNT = "equinox.start.level.thread.count"; //$NON-NLS-1$ + public static final String PROP_EQUINOX_START_LEVEL_RESTRICT_PARALLEL = "equinox.start.level.restrict.parallel"; //$NON-NLS-1$ public static final String PROP_RESOLVER_REVISION_BATCH_SIZE = "equinox.resolver.revision.batch.size"; //$NON-NLS-1$ public static final String PROP_RESOLVER_BATCH_TIMEOUT = "equinox.resolver.batch.timeout"; //$NON-NLS-1$ diff --git a/bundles/org.eclipse.osgi/pom.xml b/bundles/org.eclipse.osgi/pom.xml index 9ae03a65b..dffff72d5 100644 --- a/bundles/org.eclipse.osgi/pom.xml +++ b/bundles/org.eclipse.osgi/pom.xml @@ -19,7 +19,7 @@ </parent> <groupId>org.eclipse.osgi</groupId> <artifactId>org.eclipse.osgi</artifactId> - <version>3.14.100-SNAPSHOT</version> + <version>3.15.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> <build> |