< prev index next >

src/java.base/share/classes/java/lang/ref/ReferenceQueue.java

Print this page
rev 12453 : [mq]: fix

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.  Oracle designates this

@@ -61,14 +61,21 @@
             ReferenceQueue<?> queue = r.queue;
             if ((queue == NULL) || (queue == ENQUEUED)) {
                 return false;
             }
             assert queue == this;
-            r.queue = ENQUEUED;
             r.next = (head == null) ? r : head;
             head = r;
             queueLength++;
+            // Assignment of queue to special ENQUEUED queue must be
+            // after the reference is added to the queue's list.
+            // Otherwise, there is a race condition where the
+            // reference appears to be enqueued (isEnqueue returns
+            // true, another enqueue returns false), but polling the
+            // queue could find it still empty.  The q.head and
+            // r.queue fields are volatile, ensuring that order.
+            r.queue = ENQUEUED;
             if (r instanceof FinalReference) {
                 sun.misc.VM.addFinalRefCount(1);
             }
             lock.notifyAll();
             return true;
< prev index next >