Merge
authorkbarrett
Wed, 05 Aug 2015 03:43:31 +0200
changeset 32220 602c828cf7dc
parent 32218 c4a59b9f5c12 (current diff)
parent 32219 e613f4863973 (diff)
child 32221 2d0aa67d905f
child 32222 fed421ad9b70
Merge
--- a/jdk/src/java.base/share/classes/java/lang/ref/ReferenceQueue.java	Tue Aug 04 19:25:59 2015 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/ref/ReferenceQueue.java	Wed Aug 05 03:43:31 2015 +0200
@@ -65,10 +65,13 @@
                 return false;
             }
             assert queue == this;
-            r.queue = ENQUEUED;
             r.next = (head == null) ? r : head;
             head = r;
             queueLength++;
+            // Update r.queue *after* adding to list, to avoid race
+            // with concurrent enqueued checks and fast-path poll().
+            // Volatiles ensure ordering.
+            r.queue = ENQUEUED;
             if (r instanceof FinalReference) {
                 sun.misc.VM.addFinalRefCount(1);
             }
@@ -80,10 +83,13 @@
     private Reference<? extends T> reallyPoll() {       /* Must hold lock */
         Reference<? extends T> r = head;
         if (r != null) {
+            r.queue = NULL;
+            // Update r.queue *before* removing from list, to avoid
+            // race with concurrent enqueued checks and fast-path
+            // poll().  Volatiles ensure ordering.
             @SuppressWarnings("unchecked")
             Reference<? extends T> rn = r.next;
             head = (rn == r) ? null : rn;
-            r.queue = NULL;
             r.next = r;
             queueLength--;
             if (r instanceof FinalReference) {
--- a/jdk/test/java/lang/ref/ReferenceEnqueue.java	Tue Aug 04 19:25:59 2015 +0000
+++ b/jdk/test/java/lang/ref/ReferenceEnqueue.java	Wed Aug 05 03:43:31 2015 +0200
@@ -22,7 +22,7 @@
  */
 
 /* @test
- * @bug 4268317
+ * @bug 4268317 8132306
  * @summary Test if Reference.enqueue() works properly with GC
  */