aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleg Besedin2012-10-18 14:32:16 (EDT)
committerOleg Besedin2012-10-18 14:32:16 (EDT)
commite418dfc33aae81aff5fcd522393ac2ee89db8715 (patch)
tree35a618a4f8a14d9cc49ff6663941045c272126d8
parentbcadf392c9ebf21d6a52e3fc38c0f09379db5315 (diff)
downloadeclipse.platform.runtime-e418dfc33aae81aff5fcd522393ac2ee89db8715.zip
eclipse.platform.runtime-e418dfc33aae81aff5fcd522393ac2ee89db8715.tar.gz
eclipse.platform.runtime-e418dfc33aae81aff5fcd522393ac2ee89db8715.tar.bz2
Bug 389250 - Lots of stuff leaked when closing and reopening viewsv20121018-183216
-rw-r--r--bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/WeakGroupedListenerList.java144
1 files changed, 144 insertions, 0 deletions
diff --git a/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/WeakGroupedListenerList.java b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/WeakGroupedListenerList.java
new file mode 100644
index 0000000..e805a56
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/WeakGroupedListenerList.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright (c) 2012 IBM Corporation 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.e4.core.internal.contexts;
+
+import java.lang.ref.WeakReference;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+/**
+ * Listeners are held wrapped in weak references and are removed if no other [strong] reference
+ * exists.
+ */
+public class WeakGroupedListenerList {
+
+ public static class WeakComputationReference extends WeakReference<Computation> {
+
+ final private int hashCode;
+
+ public WeakComputationReference(Computation computation) {
+ super(computation);
+ hashCode = computation.hashCode();
+ }
+
+ public int hashCode() {
+ return hashCode;
+ }
+
+ public boolean equals(Object obj) {
+ if (obj == null)
+ return false;
+ if (!WeakComputationReference.class.equals(obj.getClass()))
+ return super.equals(obj);
+ Computation computation = get();
+ Computation otherComputation = ((WeakComputationReference) obj).get();
+ if (computation == null && otherComputation == null)
+ return true;
+ if (computation == null || otherComputation == null)
+ return false;
+ return computation.equals(otherComputation);
+ }
+ }
+
+ private Map<String, HashSet<WeakComputationReference>> listeners = new HashMap<String, HashSet<WeakComputationReference>>(10, 0.8f);
+
+ synchronized public void add(String groupName, Computation computation) {
+ HashSet<WeakComputationReference> nameListeners = listeners.get(groupName);
+ if (nameListeners == null) {
+ nameListeners = new HashSet<WeakComputationReference>(30, 0.75f);
+ nameListeners.add(new WeakComputationReference(computation));
+ listeners.put(groupName, nameListeners);
+ }
+ nameListeners.add(new WeakComputationReference(computation));
+ }
+
+ synchronized public void remove(Computation computation) {
+ WeakComputationReference ref = new WeakComputationReference(computation);
+ Collection<HashSet<WeakComputationReference>> allListeners = listeners.values();
+ for (HashSet<WeakComputationReference> group : allListeners) {
+ group.remove(ref);
+ }
+ }
+
+ synchronized public Set<String> getNames() {
+ Set<String> tmp = listeners.keySet(); // clone internal name list
+ Set<String> usedNames = new HashSet<String>(tmp.size());
+ usedNames.addAll(tmp);
+ return usedNames;
+ }
+
+ synchronized public void clear() {
+ listeners.clear();
+ }
+
+ synchronized public Set<Computation> getListeners() {
+ Collection<HashSet<WeakComputationReference>> collection = listeners.values();
+ Set<Computation> result = new HashSet<Computation>();
+ for (HashSet<WeakComputationReference> set : collection) {
+ for (Iterator<WeakComputationReference> i = set.iterator(); i.hasNext();) {
+ WeakComputationReference ref = i.next();
+ Computation computation = ref.get();
+ if (computation == null || !computation.isValid()) {
+ i.remove(); // do a clean-up while we are here
+ } else
+ result.add(computation);
+ }
+ }
+ return result;
+ }
+
+ synchronized public Set<Computation> getListeners(String groupName) {
+ HashSet<WeakComputationReference> tmp = listeners.get(groupName);
+ if (tmp == null)
+ return null;
+ Set<Computation> result = new HashSet<Computation>(tmp.size());
+
+ for (Iterator<WeakComputationReference> i = tmp.iterator(); i.hasNext();) {
+ WeakComputationReference ref = i.next();
+ Computation computation = ref.get();
+ if (computation == null || !computation.isValid()) {
+ i.remove(); // do a clean-up while we are here
+ } else
+ result.add(computation);
+ }
+ return result;
+ }
+
+ synchronized public void cleanup() {
+ boolean cleanGroups = false;
+ for (HashSet<WeakComputationReference> set : listeners.values()) {
+ for (Iterator<WeakComputationReference> i = set.iterator(); i.hasNext();) {
+ WeakComputationReference ref = i.next();
+ Computation computation = ref.get();
+ if (computation == null || !computation.isValid())
+ i.remove();
+ }
+ if (set.isEmpty())
+ cleanGroups = true;
+ }
+ if (cleanGroups) {
+ Set<Entry<String, HashSet<WeakComputationReference>>> entries = listeners.entrySet();
+ for (Iterator<Entry<String, HashSet<WeakComputationReference>>> i = entries.iterator(); i.hasNext();) {
+ Entry<String, HashSet<WeakComputationReference>> entry = i.next();
+ HashSet<WeakComputationReference> value = entry.getValue();
+ if (value == null || value.isEmpty())
+ i.remove();
+ }
+ }
+ }
+
+}