From 39b193b6f4b72bd6c08170f53001e7cfdaa51318 Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Sun, 3 Sep 2017 00:06:59 +0200 Subject: [PATCH] Remove workaround for bug in Java's ReferenceQueue Sun's Java 5, 6, 7 implementation had a bug [1] where a Reference can be enqueued and dequeued twice on the same reference queue due to a race condition within ReferenceQueue.enqueue(Reference). This bug was fixed for Java 8 [2] hence remove the workaround. [1] http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6837858 [2] http://hg.openjdk.java.net/jdk8/jdk8/jdk/rev/858c75eb83b5 Change-Id: I2deeb607e3d237f9f825a207533acdee305c7e73 Signed-off-by: Matthias Sohn --- .../internal/storage/file/WindowCache.java | 42 ++++--------------- 1 file changed, 9 insertions(+), 33 deletions(-) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java index a525c8511..61960068b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java @@ -496,31 +496,16 @@ public class WindowCache { private void gc() { Ref r; while ((r = (Ref) queue.poll()) != null) { - // Sun's Java 5 and 6 implementation have a bug where a Reference - // can be enqueued and dequeued twice on the same reference queue - // due to a race condition within ReferenceQueue.enqueue(Reference). - // - // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6837858 - // - // We CANNOT permit a Reference to come through us twice, as it will - // skew the resource counters we maintain. Our canClear() check here - // provides a way to skip the redundant dequeues, if any. - // - if (r.canClear()) { - clear(r); - - boolean found = false; - final int s = slot(r.pack, r.position); - final Entry e1 = table.get(s); - for (Entry n = e1; n != null; n = n.next) { - if (n.ref == r) { - n.dead = true; - found = true; - break; - } - } - if (found) + clear(r); + + final int s = slot(r.pack, r.position); + final Entry e1 = table.get(s); + for (Entry n = e1; n != null; n = n.next) { + if (n.ref == r) { + n.dead = true; table.compareAndSet(s, e1, clean(e1)); + break; + } } } } @@ -581,8 +566,6 @@ public class WindowCache { long lastAccess; - private boolean cleared; - protected Ref(final PackFile pack, final long position, final ByteWindow v, final ReferenceQueue queue) { super(v, queue); @@ -590,13 +573,6 @@ public class WindowCache { this.position = position; this.size = v.size(); } - - final synchronized boolean canClear() { - if (cleared) - return false; - cleared = true; - return true; - } } private static final class Lock {