From 314feb19b80065b9be8281b70b045489e9b4c418 Mon Sep 17 00:00:00 2001
From: Glyn Normington
Date: Tue, 1 Nov 2011 14:30:00 +0000
Subject: bug 361905: fix cleanup of bundleId->Region mapping on region removal
---
.../internal/region/BundleIdToRegionMapping.java | 8 +++-
.../region/StandardBundleIdToRegionMapping.java | 17 +++++++
.../internal/region/StandardRegionDigraph.java | 55 ++++++++++++++++++----
3 files changed, 70 insertions(+), 10 deletions(-)
(limited to 'bundles/org.eclipse.equinox.region')
diff --git a/bundles/org.eclipse.equinox.region/src/org/eclipse/equinox/internal/region/BundleIdToRegionMapping.java b/bundles/org.eclipse.equinox.region/src/org/eclipse/equinox/internal/region/BundleIdToRegionMapping.java
index 865e71e55..a6a3802fc 100644
--- a/bundles/org.eclipse.equinox.region/src/org/eclipse/equinox/internal/region/BundleIdToRegionMapping.java
+++ b/bundles/org.eclipse.equinox.region/src/org/eclipse/equinox/internal/region/BundleIdToRegionMapping.java
@@ -29,8 +29,6 @@ public interface BundleIdToRegionMapping {
* If the bundle id is already associated with the given region, there is no
* effect on the association and no exception is thrown.
*
- * TODO: need to check type of Region? Validity of region?
- *
* @param bundleId the bundle id to be associated
* @param region the {@link Region} with which the bundle id is to be associated
* @throws BundleException
@@ -45,6 +43,12 @@ public interface BundleIdToRegionMapping {
*/
void dissociateBundle(long bundleId);
+ /**
+ * Dissociates any bundle ids which may be associated with the given region.
+ * @param region the {@link Region} to be dissociated
+ */
+ void dissociateRegion(Region region);
+
/**
* Returns the {@link Region} associated with the given bundle id or null
* if the given bundle id is not associated with a region.
diff --git a/bundles/org.eclipse.equinox.region/src/org/eclipse/equinox/internal/region/StandardBundleIdToRegionMapping.java b/bundles/org.eclipse.equinox.region/src/org/eclipse/equinox/internal/region/StandardBundleIdToRegionMapping.java
index 921053582..0a22b88db 100644
--- a/bundles/org.eclipse.equinox.region/src/org/eclipse/equinox/internal/region/StandardBundleIdToRegionMapping.java
+++ b/bundles/org.eclipse.equinox.region/src/org/eclipse/equinox/internal/region/StandardBundleIdToRegionMapping.java
@@ -12,6 +12,7 @@
package org.eclipse.equinox.internal.region;
import java.util.*;
+import java.util.Map.Entry;
import org.eclipse.equinox.region.Region;
import org.osgi.framework.BundleException;
@@ -94,4 +95,20 @@ final class StandardBundleIdToRegionMapping implements BundleIdToRegionMapping {
return this.bundleToRegion.get(bundleId);
}
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void dissociateRegion(Region region) {
+ synchronized (this.monitor) {
+ Iterator> iterator = this.bundleToRegion.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Entry entry = iterator.next();
+ if (entry.getValue() == region) {
+ iterator.remove();
+ }
+ }
+ }
+ }
}
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 4837dd8ca..d04c25a0b 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
@@ -39,6 +39,8 @@ public final class StandardRegionDigraph implements BundleIdToRegionMapping, Reg
private final Set regions = new HashSet();
+ // Alien calls may be made to the following object while this.monitor is locked
+ // as this.monitor is higher in the lock hierarchy than this object's own monitor.
private final BundleIdToRegionMapping bundleIdToRegionMapping;
/* edges maps a given region to an immutable set of edges with their tail at the given region. To update
@@ -272,6 +274,7 @@ public final class StandardRegionDigraph implements BundleIdToRegionMapping, Reg
}
}
}
+ this.bundleIdToRegionMapping.dissociateRegion(region);
incrementUpdateCount();
}
}
@@ -496,10 +499,15 @@ public final class StandardRegionDigraph implements BundleIdToRegionMapping, Reg
return this.defaultRegion;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void associateBundleWithRegion(long bundleId, Region region) throws BundleException {
- this.bundleIdToRegionMapping.associateBundleWithRegion(bundleId, region);
- incrementUpdateCount();
+ synchronized (this.monitor) {
+ this.bundleIdToRegionMapping.associateBundleWithRegion(bundleId, region);
+ incrementUpdateCount();
+ }
}
private void incrementUpdateCount() {
@@ -509,26 +517,57 @@ public final class StandardRegionDigraph implements BundleIdToRegionMapping, Reg
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void dissociateBundle(long bundleId) {
- this.bundleIdToRegionMapping.dissociateBundle(bundleId);
- incrementUpdateCount();
+ synchronized (this.monitor) {
+ this.bundleIdToRegionMapping.dissociateBundle(bundleId);
+ incrementUpdateCount();
+ }
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public boolean isBundleAssociatedWithRegion(long bundleId, Region region) {
- return this.bundleIdToRegionMapping.isBundleAssociatedWithRegion(bundleId, region);
+ synchronized (this.monitor) {
+ return this.bundleIdToRegionMapping.isBundleAssociatedWithRegion(bundleId, region);
+ }
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public Set getBundleIds(Region region) {
- return this.bundleIdToRegionMapping.getBundleIds(region);
+ synchronized (this.monitor) {
+ return this.bundleIdToRegionMapping.getBundleIds(region);
+ }
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void clear() {
- this.bundleIdToRegionMapping.clear();
- incrementUpdateCount();
+ synchronized (this.monitor) {
+ this.bundleIdToRegionMapping.clear();
+ incrementUpdateCount();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void dissociateRegion(Region region) {
+ synchronized (this.monitor) {
+ this.bundleIdToRegionMapping.dissociateRegion(region);
+ incrementUpdateCount();
+ }
}
}
--
cgit v1.2.3