FELIX-3564: Fixed memory leak in ServiceRegistryCache
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1351732 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/FilterIndex.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/FilterIndex.java
index 62116f7..df648e9 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/FilterIndex.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/FilterIndex.java
@@ -42,6 +42,6 @@
public void serviceChanged(ServiceEvent event);
/** Adds a service listener to this filter index. */
public void addServiceListener(ServiceListener listener, String filter);
- /** Removes a service listener from this filter index. */
+ /** Removes a service listener from this filter index. If the listener is not present in the filter index, this method does nothing. */
public void removeServiceListener(ServiceListener listener);
}
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/index/AdapterFilterIndex.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/index/AdapterFilterIndex.java
index 4d466e2..2543746 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/index/AdapterFilterIndex.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/index/AdapterFilterIndex.java
@@ -172,12 +172,15 @@
public void removeServiceListener(ServiceListener listener) {
synchronized (m_sidToListenersMap) {
String filter = (String) m_listenerToFilterMap.remove(listener);
- FilterData data = getFilterData(null, filter);
- if (data != null) {
- Long sidObject = Long.valueOf(data.serviceId);
- List /* ServiceListener */ listeners = (List) m_sidToListenersMap.get(sidObject);
- if (listeners != null) {
- listeners.remove(listener);
+ if (filter != null) {
+ // the listener does exist
+ FilterData data = getFilterData(null, filter);
+ if (data != null) {
+ Long sidObject = Long.valueOf(data.serviceId);
+ List /* ServiceListener */ listeners = (List) m_sidToListenersMap.get(sidObject);
+ if (listeners != null) {
+ listeners.remove(listener);
+ }
}
}
}
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/index/AspectFilterIndex.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/index/AspectFilterIndex.java
index 70bf333..4e79eb4 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/index/AspectFilterIndex.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/index/AspectFilterIndex.java
@@ -189,14 +189,17 @@
public void removeServiceListener(ServiceListener listener) {
synchronized (m_sidToRankingToListenersMap) {
String filter = (String) m_listenerToFilterMap.remove(listener);
- FilterData data = getFilterData(null, filter);
- if (data != null) {
- synchronized (m_sidToRankingToListenersMap) {
- SortedMap /* <Integer, ServiceListener> */ rankingToListenersMap = (SortedMap) m_sidToRankingToListenersMap.get(Long.valueOf(data.serviceId));
- if (rankingToListenersMap != null) {
- rankingToListenersMap.remove(Integer.valueOf(data.ranking));
- }
- }
+ if (filter != null) {
+ // the listener does exist
+ FilterData data = getFilterData(null, filter);
+ if (data != null) {
+ synchronized (m_sidToRankingToListenersMap) {
+ SortedMap /* <Integer, ServiceListener> */ rankingToListenersMap = (SortedMap) m_sidToRankingToListenersMap.get(Long.valueOf(data.serviceId));
+ if (rankingToListenersMap != null) {
+ rankingToListenersMap.remove(Integer.valueOf(data.ranking));
+ }
+ }
+ }
}
}
}
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/index/BundleContextInterceptor.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/index/BundleContextInterceptor.java
index 51cc43d..e39de62 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/index/BundleContextInterceptor.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/index/BundleContextInterceptor.java
@@ -64,13 +64,13 @@
}
public void removeServiceListener(ServiceListener listener) {
- FilterIndex filterIndex = m_cache.hasFilterIndexFor(null, null);
- if (filterIndex != null) {
- filterIndex.removeServiceListener(listener);
- }
- else {
- m_context.removeServiceListener(listener);
- }
+ // remove servicelistener. although it would be prettier to find the correct filterindex first it's
+ // probaby faster to do a brute force removal.
+ Iterator filterIndexIterator = m_cache.getFilterIndices().iterator();
+ while (filterIndexIterator.hasNext()) {
+ ((FilterIndex) filterIndexIterator.next()).removeServiceListener(listener);
+ }
+ m_context.removeServiceListener(listener);
}
public ServiceReference[] getServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/index/MultiPropertyExactFilter.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/index/MultiPropertyExactFilter.java
index fb4f313..f0b7705 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/index/MultiPropertyExactFilter.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/index/MultiPropertyExactFilter.java
@@ -398,19 +398,22 @@
public void removeServiceListener(ServiceListener listener) {
synchronized (m_keyToListenersMap) {
String filter = (String) m_listenerToFilterMap.remove(listener);
- List keys = createKeysFromFilter(null, filter);
- Iterator iterator = keys.iterator();
- while (iterator.hasNext()) {
- String key = (String) iterator.next();
-
- boolean result = filter != null;
- if (result) {
- List /* <ServiceListener> */ listeners = (List) m_keyToListenersMap.get(key);
- if (listeners != null) {
- listeners.remove(listener);
- }
- // TODO actually, if listeners == null that would be strange....
- }
+ if (filter != null) {
+ // the listener does exist
+ List keys = createKeysFromFilter(null, filter);
+ Iterator iterator = keys.iterator();
+ while (iterator.hasNext()) {
+ String key = (String) iterator.next();
+
+ boolean result = filter != null;
+ if (result) {
+ List /* <ServiceListener> */ listeners = (List) m_keyToListenersMap.get(key);
+ if (listeners != null) {
+ listeners.remove(listener);
+ }
+ // TODO actually, if listeners == null that would be strange....
+ }
+ }
}
}
}
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/index/ServiceRegistryCache.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/index/ServiceRegistryCache.java
index 3e2bcd2..41f7fd6 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/index/ServiceRegistryCache.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/index/ServiceRegistryCache.java
@@ -169,4 +169,8 @@
sb.append("]");
return sb.toString();
}
+
+ public List getFilterIndices() {
+ return m_filterIndexList;
+ }
}