From 42562c2d53d2c583f9c8056f7e312aad4df20333 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mayer Date: Tue, 15 Nov 2016 21:58:26 +0000 Subject: [PATCH] Added synchronisation directives in WeakValueMap This correct various random crashes occuring with Internet Explorer when push updates are used. --- src/eu/webtoolkit/jwt/utils/WeakValueMap.java | 153 ++++++++++-------- 1 file changed, 88 insertions(+), 65 deletions(-) diff --git a/src/eu/webtoolkit/jwt/utils/WeakValueMap.java b/src/eu/webtoolkit/jwt/utils/WeakValueMap.java index 43fed4b88..40d2fc903 100644 --- a/src/eu/webtoolkit/jwt/utils/WeakValueMap.java +++ b/src/eu/webtoolkit/jwt/utils/WeakValueMap.java @@ -13,20 +13,23 @@ public class WeakValueMap implements Map { private static class KeyedWeakReference extends WeakReference { private K key; - + KeyedWeakReference(K key, V value, ReferenceQueue referenceQueue) { super(value, referenceQueue); this.key = key; } - + K getKey() { return key; } } private HashMap> storage = new HashMap>(); - + public int size() { prune(); - return storage.size(); + synchronized(storage) + { + return storage.size(); + } } public boolean isEmpty() { @@ -35,109 +38,129 @@ public boolean isEmpty() { public boolean containsKey(Object key) { prune(); - return storage.containsKey(key); + synchronized(storage) { + return storage.containsKey(key); + } } public boolean containsValue(Object value) { - for (KeyedWeakReference v : storage.values()) { - V vv = v.get(); - if (vv != null) - if (value.equals(vv)) - return true; + synchronized(storage) { + for (KeyedWeakReference v : storage.values()) { + V vv = v.get(); + if (vv != null) + if (value.equals(vv)) + return true; + } } return false; } public V get(Object key) { prune(); - WeakReference v = storage.get(key); - if (v != null) - return v.get(); - else - return null; + synchronized(storage) { + WeakReference v = storage.get(key); + if (v != null) + return v.get(); + else + return null; + } } public V put(K key, V value) { - storage.put(key, new KeyedWeakReference(key, value, referenceQueue)); - return value; + synchronized(storage) { + storage.put(key, new KeyedWeakReference(key, value, referenceQueue)); + return value; + } } public V remove(Object key) { - KeyedWeakReference k = storage.get(key); - if (k != null) { - V result = k.get(); - storage.remove(key); - return result; - } else - return null; + synchronized(storage) { + KeyedWeakReference k = storage.get(key); + if (k != null) { + V result = k.get(); + storage.remove(key); + return result; + } else + return null; + } } public void putAll(Map m) { - for (K k : m.keySet()) - put(k, m.get(k)); + synchronized(storage) { + for (K k : m.keySet()) + put(k, m.get(k)); + } } public void clear() { - storage.clear(); + synchronized(storage) { + storage.clear(); + } } public Set keySet() { prune(); - return storage.keySet(); + synchronized(storage) { + return storage.keySet(); + } } public Collection values() { - Set result = new HashSet(); - - for (KeyedWeakReference v : storage.values()) { - V vv = v.get(); - if (vv != null) - result.add(vv); + synchronized(storage) { + Set result = new HashSet(); + + for (KeyedWeakReference v : storage.values()) { + V vv = v.get(); + if (vv != null) + result.add(vv); + } + + return result; } - - return result; } public Set> entrySet() { prune(); @SuppressWarnings("unused") - Set> result = new HashSet>(); - - for (final java.util.Map.Entry> i : storage.entrySet()) { - final V vv = i.getValue().get(); - if (vv != null) - result.add(new Entry() { - @Override - public K getKey() { - return i.getKey(); - } - - @Override - public V getValue() { - return vv; - } - - @Override - public V setValue(V value) { - throw new RuntimeException("Not implemented"); - } - }); + Set> result = new HashSet>(); + synchronized(storage) { + for (final java.util.Map.Entry> i : storage.entrySet()) { + final V vv = i.getValue().get(); + if (vv != null) + result.add(new Entry() { + @Override + public K getKey() { + return i.getKey(); + } + + @Override + public V getValue() { + return vv; + } + + @Override + public V setValue(V value) { + throw new RuntimeException("Not implemented"); + } + }); + } } - return result; } private void prune() { //System.gc(); //Runtime.getRuntime().runFinalization(); - for (;;) { - @SuppressWarnings("unchecked") - KeyedWeakReference ref = (KeyedWeakReference) referenceQueue.poll(); - if (ref != null) { - storage.remove(ref.getKey()); - } else - break; + synchronized(storage) { + for (;;) { + @SuppressWarnings("unchecked") + KeyedWeakReference ref = (KeyedWeakReference) referenceQueue.poll(); + if (ref != null) { + storage.remove(ref.getKey()); + } else + break; + } } } }