Browse Source

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 <matthias.sohn@sap.com>
stable-4.9
Matthias Sohn 7 years ago
parent
commit
39b193b6f4
  1. 26
      org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java

26
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java

@ -496,32 +496,17 @@ 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;
table.compareAndSet(s, e1, clean(e1));
break;
}
}
if (found)
table.compareAndSet(s, e1, clean(e1));
}
}
}
@ -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<ByteWindow> 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 {

Loading…
Cancel
Save