diff options
author | Thomas Watson | 2020-02-21 18:15:52 +0000 |
---|---|---|
committer | Thomas Watson | 2020-02-21 18:15:52 +0000 |
commit | c7ec01ea86f16e1890a162c699ae5f11f3542e34 (patch) | |
tree | d8a25ae873e98193f4e874868719388c4b1fd4c6 | |
parent | f1e3d41558884625da6d220f3931265796dede2e (diff) | |
download | rt.equinox.framework-c7ec01ea86f16e1890a162c699ae5f11f3542e34.tar.gz rt.equinox.framework-c7ec01ea86f16e1890a162c699ae5f11f3542e34.tar.xz rt.equinox.framework-c7ec01ea86f16e1890a162c699ae5f11f3542e34.zip |
Bug 559840 - handle duplicate ConnectContent with ConnectBundleFile
We need to make sure we only create one ConnectBundleFile instance per
ConnectContent instance. Otherwise our managing of open/close
operations will get messed up.
Change-Id: I6fa3f9857726a39eaee8e07f7e11abdee9881abb
3 files changed, 33 insertions, 2 deletions
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ConnectTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ConnectTests.java index 820fc14ab..2fef34ec0 100644 --- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ConnectTests.java +++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ConnectTests.java @@ -689,6 +689,12 @@ public class ConnectTests extends AbstractBundleTests { TestConnectContent newContent = m.getContent(); assertTrue("New content is not open.", newContent.isOpen()); assertFalse("Original content is open.", original.isOpen()); + + // now update with no new content + b.update(); + assertNull(b.getEntry("doesNotExist.txt")); + assertTrue("New content is not open.", newContent.isOpen()); + assertFalse("Original content is open.", original.isOpen()); } catch (Throwable t) { sneakyThrow(t); } diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainer.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainer.java index ed7078e85..04f680981 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainer.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainer.java @@ -15,6 +15,7 @@ package org.eclipse.osgi.internal.framework; import java.io.File; import java.io.IOException; +import java.lang.ref.WeakReference; import java.lang.reflect.Method; import java.net.URL; import java.security.AccessController; @@ -24,6 +25,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.WeakHashMap; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.Executors; @@ -32,6 +34,8 @@ import java.util.concurrent.ThreadFactory; import org.eclipse.osgi.framework.eventmgr.ListenerQueue; import org.eclipse.osgi.framework.log.FrameworkLogEntry; import org.eclipse.osgi.framework.util.SecureAction; +import org.eclipse.osgi.internal.connect.ConnectBundleFile; +import org.eclipse.osgi.internal.debug.Debug; import org.eclipse.osgi.internal.framework.legacy.PackageAdminImpl; import org.eclipse.osgi.internal.framework.legacy.StartLevelImpl; import org.eclipse.osgi.internal.hookregistry.ClassLoaderHook; @@ -41,7 +45,9 @@ import org.eclipse.osgi.internal.log.EquinoxLogServices; import org.eclipse.osgi.internal.messages.Msg; import org.eclipse.osgi.internal.serviceregistry.ServiceRegistry; import org.eclipse.osgi.signedcontent.SignedContentFactory; +import org.eclipse.osgi.storage.BundleInfo; import org.eclipse.osgi.storage.Storage; +import org.eclipse.osgi.storage.bundlefile.MRUBundleFileList; import org.eclipse.osgi.util.ManifestElement; import org.eclipse.osgi.util.NLS; import org.osgi.framework.AdminPermission; @@ -49,6 +55,7 @@ import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; import org.osgi.framework.Constants; +import org.osgi.framework.connect.ConnectContent; import org.osgi.framework.connect.ConnectModule; import org.osgi.framework.connect.ModuleConnector; import org.osgi.service.packageadmin.PackageAdmin; @@ -362,6 +369,7 @@ public class EquinoxContainer implements ThreadFactory, Runnable { public static class ConnectModules { final ModuleConnector moduleConnector; private final ConcurrentMap<String, ConnectModule> connectModules = new ConcurrentHashMap<>(); + private final WeakHashMap<ConnectContent, WeakReference<ConnectBundleFile>> contents = new WeakHashMap<>(); public ConnectModules(ModuleConnector moduleConnector) { this.moduleConnector = moduleConnector; @@ -381,6 +389,23 @@ public class EquinoxContainer implements ThreadFactory, Runnable { return result; } + public ConnectBundleFile getConnectBundleFile(ConnectModule module, File basefile, + BundleInfo.Generation generation, MRUBundleFileList mruList, Debug debug) throws IOException { + ConnectContent content = module.getContent(); + synchronized (contents) { + WeakReference<ConnectBundleFile> ref = contents.get(content); + if (ref != null) { + ConnectBundleFile bundleFile = ref.get(); + if (bundleFile != null) { + return bundleFile; + } + } + ConnectBundleFile bundleFile = new ConnectBundleFile(module, basefile, generation, mruList, debug); + contents.put(content, new WeakReference<>(bundleFile)); + return bundleFile; + } + } + public ModuleConnector getModuleConnector() { return moduleConnector; } diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/Storage.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/Storage.java index 730206a6c..0671a94c9 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/Storage.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/Storage.java @@ -67,7 +67,6 @@ import org.eclipse.osgi.framework.log.FrameworkLogEntry; import org.eclipse.osgi.framework.util.FilePath; import org.eclipse.osgi.framework.util.ObjectPool; import org.eclipse.osgi.framework.util.SecureAction; -import org.eclipse.osgi.internal.connect.ConnectBundleFile; import org.eclipse.osgi.internal.debug.Debug; import org.eclipse.osgi.internal.framework.EquinoxConfiguration; import org.eclipse.osgi.internal.framework.EquinoxContainer; @@ -1182,7 +1181,8 @@ public class Storage { } try { if (connectModule != null && isBase) { - result = new ConnectBundleFile(connectModule, content, generation, mruList, getConfiguration().getDebug()); + result = equinoxContainer.getConnectModules().getConnectBundleFile(connectModule, content, generation, + mruList, getConfiguration().getDebug()); } else if (isDirectory) { boolean strictPath = Boolean.parseBoolean(equinoxContainer.getConfiguration().getConfiguration(EquinoxConfiguration.PROPERTY_STRICT_BUNDLE_ENTRY_PATH, Boolean.FALSE.toString())); result = new DirBundleFile(content, strictPath); |