diff options
author | Thomas Watson | 2015-08-28 20:44:48 +0000 |
---|---|---|
committer | Thomas Watson | 2015-08-28 20:44:48 +0000 |
commit | 83153894ca0b83565d0631d3106447ef54a9b4f7 (patch) | |
tree | d9a5ff171d9e0e760d0059f19c0d292632f63111 /bundles/org.eclipse.equinox.region | |
parent | 45235814960e541a013744b825e111e837cc5c03 (diff) | |
download | rt.equinox.bundles-83153894ca0b83565d0631d3106447ef54a9b4f7.tar.gz rt.equinox.bundles-83153894ca0b83565d0631d3106447ef54a9b4f7.tar.xz rt.equinox.bundles-83153894ca0b83565d0631d3106447ef54a9b4f7.zip |
Bug 476145 - [region] performance issue with large number of bundle listeners and bundle eventsI20150901-0800
Diffstat (limited to 'bundles/org.eclipse.equinox.region')
3 files changed, 41 insertions, 13 deletions
diff --git a/bundles/org.eclipse.equinox.region/src/org/eclipse/equinox/internal/region/StandardRegionDigraph.java b/bundles/org.eclipse.equinox.region/src/org/eclipse/equinox/internal/region/StandardRegionDigraph.java index e59237027..fedb941e4 100644 --- a/bundles/org.eclipse.equinox.region/src/org/eclipse/equinox/internal/region/StandardRegionDigraph.java +++ b/bundles/org.eclipse.equinox.region/src/org/eclipse/equinox/internal/region/StandardRegionDigraph.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011, 2014 VMware Inc. + * Copyright (c) 2011, 2015 VMware Inc. and others * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -87,7 +87,7 @@ public final class StandardRegionDigraph implements BundleIdToRegionMapping, Reg this.resolverHookFactory = new RegionResolverHookFactory(this); this.bundleFindHook = new RegionBundleFindHook(this, bundleContext == null ? 0 : bundleContext.getBundle().getBundleId()); - this.bundleEventHook = new RegionBundleEventHook(this, this.bundleFindHook, this.threadLocal); + this.bundleEventHook = new RegionBundleEventHook(this, this.threadLocal, bundleContext == null ? 0 : bundleContext.getBundle().getBundleId()); Object hook; try { hook = new RegionBundleCollisionHook(this, this.threadLocal); diff --git a/bundles/org.eclipse.equinox.region/src/org/eclipse/equinox/internal/region/hook/RegionBundleEventHook.java b/bundles/org.eclipse.equinox.region/src/org/eclipse/equinox/internal/region/hook/RegionBundleEventHook.java index 3edb5117b..8b27915f2 100644 --- a/bundles/org.eclipse.equinox.region/src/org/eclipse/equinox/internal/region/hook/RegionBundleEventHook.java +++ b/bundles/org.eclipse.equinox.region/src/org/eclipse/equinox/internal/region/hook/RegionBundleEventHook.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011 VMware Inc. + * Copyright (c) 2011, 2015 VMware Inc. and others * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -16,7 +16,6 @@ import org.eclipse.equinox.region.Region; import org.eclipse.equinox.region.RegionDigraph; import org.osgi.framework.*; import org.osgi.framework.hooks.bundle.EventHook; -import org.osgi.framework.hooks.bundle.FindHook; /** * {@link RegionBundleEventHook} manages the visibility of bundle events across regions according to the @@ -33,14 +32,14 @@ public final class RegionBundleEventHook implements EventHook { private final RegionDigraph regionDigraph; - private final FindHook bundleFindHook; - private final ThreadLocal<Region> threadLocal; - public RegionBundleEventHook(RegionDigraph regionDigraph, FindHook bundleFindBook, ThreadLocal<Region> threadLocal) { + private final long hookImplID; + + public RegionBundleEventHook(RegionDigraph regionDigraph, ThreadLocal<Region> threadLocal, long hookImplID) { this.regionDigraph = regionDigraph; - this.bundleFindHook = bundleFindBook; this.threadLocal = threadLocal; + this.hookImplID = hookImplID; } /** @@ -52,10 +51,35 @@ public final class RegionBundleEventHook implements EventHook { if (event.getType() == BundleEvent.INSTALLED) { bundleInstalled(eventBundle, event.getOrigin()); } + Map<Region, Boolean> regionAccess = new HashMap<Region, Boolean>(); Iterator<BundleContext> i = contexts.iterator(); while (i.hasNext()) { - if (!find(i.next(), eventBundle)) { + Bundle bundle = RegionBundleFindHook.getBundle(i.next()); + if (bundle == null) { + // no bundle for context remove access from it i.remove(); + continue; + } + + long bundleID = bundle.getBundleId(); + if (bundleID == 0 || bundleID == hookImplID) { + // The system bundle and the hook impl bundle can see all bundles + continue; + } + Region region = regionDigraph.getRegion(bundle); + if (region == null) { + // no region for context remove access from it + i.remove(); + } else { + Boolean accessible = regionAccess.get(region); + if (accessible == null) { + // we have not checked this region's access do it now + accessible = isAccessible(region, eventBundle); + regionAccess.put(region, accessible); + } + if (!accessible) { + i.remove(); + } } } if (event.getType() == BundleEvent.UNINSTALLED) { @@ -63,10 +87,10 @@ public final class RegionBundleEventHook implements EventHook { } } - private boolean find(BundleContext finderBundleContext, Bundle candidateBundle) { + private boolean isAccessible(Region region, Bundle candidateBundle) { Collection<Bundle> candidates = new ArrayList<Bundle>(1); candidates.add(candidateBundle); - this.bundleFindHook.find(finderBundleContext, candidates); + RegionBundleFindHook.find(region, candidates); return !candidates.isEmpty(); } diff --git a/bundles/org.eclipse.equinox.region/src/org/eclipse/equinox/internal/region/hook/RegionBundleFindHook.java b/bundles/org.eclipse.equinox.region/src/org/eclipse/equinox/internal/region/hook/RegionBundleFindHook.java index 6c41f73d1..9cba36445 100644 --- a/bundles/org.eclipse.equinox.region/src/org/eclipse/equinox/internal/region/hook/RegionBundleFindHook.java +++ b/bundles/org.eclipse.equinox.region/src/org/eclipse/equinox/internal/region/hook/RegionBundleFindHook.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2013 VMware Inc. + * Copyright (c) 2013, 2015 VMware Inc. and others * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -53,6 +53,10 @@ public final class RegionBundleFindHook implements FindHook { } Region finderRegion = this.regionDigraph.getRegion(finderBundle); + RegionBundleFindHook.find(finderRegion, bundles); + } + + static void find(Region finderRegion, Collection<Bundle> bundles) { if (finderRegion == null) { bundles.clear(); return; @@ -65,7 +69,7 @@ public final class RegionBundleFindHook implements FindHook { bundles.retainAll(allowed); } - class Visitor extends RegionDigraphVisitorBase<Bundle> { + static class Visitor extends RegionDigraphVisitorBase<Bundle> { Visitor(Collection<Bundle> candidates) { super(candidates); |