提交 93fa841f 编写于 作者: M martin

8197812: (ref) Data race in Finalizer

Reviewed-by: plevart, mchung
上级 74361b06
...@@ -36,18 +36,18 @@ final class Finalizer extends FinalReference<Object> { /* Package-private; must ...@@ -36,18 +36,18 @@ final class Finalizer extends FinalReference<Object> { /* Package-private; must
class */ class */
private static ReferenceQueue<Object> queue = new ReferenceQueue<>(); private static ReferenceQueue<Object> queue = new ReferenceQueue<>();
/** Head of doubly linked list of Finalizers awaiting finalization. */
private static Finalizer unfinalized = null; private static Finalizer unfinalized = null;
/** Lock guarding access to unfinalized list. */
private static final Object lock = new Object(); private static final Object lock = new Object();
private Finalizer private Finalizer next, prev;
next = null,
prev = null;
private boolean hasBeenFinalized() { private Finalizer(Object finalizee) {
return (next == this); super(finalizee, queue);
} // push onto unfinalized
private void add() {
synchronized (lock) { synchronized (lock) {
if (unfinalized != null) { if (unfinalized != null) {
this.next = unfinalized; this.next = unfinalized;
...@@ -57,31 +57,6 @@ final class Finalizer extends FinalReference<Object> { /* Package-private; must ...@@ -57,31 +57,6 @@ final class Finalizer extends FinalReference<Object> { /* Package-private; must
} }
} }
private void remove() {
synchronized (lock) {
if (unfinalized == this) {
if (this.next != null) {
unfinalized = this.next;
} else {
unfinalized = this.prev;
}
}
if (this.next != null) {
this.next.prev = this.prev;
}
if (this.prev != null) {
this.prev.next = this.next;
}
this.next = this; /* Indicates that this has been finalized */
this.prev = this;
}
}
private Finalizer(Object finalizee) {
super(finalizee, queue);
add();
}
static ReferenceQueue<Object> getQueue() { static ReferenceQueue<Object> getQueue() {
return queue; return queue;
} }
...@@ -91,11 +66,24 @@ final class Finalizer extends FinalReference<Object> { /* Package-private; must ...@@ -91,11 +66,24 @@ final class Finalizer extends FinalReference<Object> { /* Package-private; must
new Finalizer(finalizee); new Finalizer(finalizee);
} }
private void runFinalizer(JavaLangAccess jla) { private void deregisterAndRunFinalizer(JavaLangAccess jla) {
synchronized (this) { synchronized (lock) {
if (hasBeenFinalized()) return; if (this.next == this) // already finalized
remove(); return;
// unlink from unfinalized
if (unfinalized == this)
unfinalized = this.next;
else
this.prev.next = this.next;
if (this.next != null)
this.next.prev = this.prev;
this.prev = null;
this.next = this; // mark as finalized
} }
runFinalizer(jla);
}
private void runFinalizer(JavaLangAccess jla) {
try { try {
Object finalizee = this.get(); Object finalizee = this.get();
if (finalizee != null && !(finalizee instanceof java.lang.Enum)) { if (finalizee != null && !(finalizee instanceof java.lang.Enum)) {
...@@ -155,11 +143,8 @@ final class Finalizer extends FinalReference<Object> { /* Package-private; must ...@@ -155,11 +143,8 @@ final class Finalizer extends FinalReference<Object> { /* Package-private; must
return; return;
final JavaLangAccess jla = SharedSecrets.getJavaLangAccess(); final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
running = true; running = true;
for (;;) { for (Finalizer f; (f = (Finalizer)queue.poll()) != null; )
Finalizer f = (Finalizer)queue.poll(); f.deregisterAndRunFinalizer(jla);
if (f == null) break;
f.runFinalizer(jla);
}
} }
}); });
} }
...@@ -179,11 +164,15 @@ final class Finalizer extends FinalReference<Object> { /* Package-private; must ...@@ -179,11 +164,15 @@ final class Finalizer extends FinalReference<Object> { /* Package-private; must
final JavaLangAccess jla = SharedSecrets.getJavaLangAccess(); final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
running = true; running = true;
for (;;) { for (;;) {
// "pollFirst" from unfinalized
Finalizer f; Finalizer f;
synchronized (lock) { synchronized (lock) {
f = unfinalized; f = unfinalized;
if (f == null) break; if (f == null) break;
unfinalized = f.next; unfinalized = f.next;
if (unfinalized != null)
unfinalized.prev = null;
f.next = f; // mark as finalized
} }
f.runFinalizer(jla); f.runFinalizer(jla);
}}}); }}});
...@@ -214,7 +203,7 @@ final class Finalizer extends FinalReference<Object> { /* Package-private; must ...@@ -214,7 +203,7 @@ final class Finalizer extends FinalReference<Object> { /* Package-private; must
for (;;) { for (;;) {
try { try {
Finalizer f = (Finalizer)queue.remove(); Finalizer f = (Finalizer)queue.remove();
f.runFinalizer(jla); f.deregisterAndRunFinalizer(jla);
} catch (InterruptedException x) { } catch (InterruptedException x) {
// ignore and continue // ignore and continue
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册