changeset 1595:69396f593772

6871697: LinkedBlockingQueue Iterator/remove/poll race Summary: More checks for node.next == node Reviewed-by: martin, dholmes, chegar
author dl
date Tue, 25 Aug 2009 19:19:42 -0700
parents 2607e571a6d5
children aeaf7b138d90
files src/share/classes/java/util/concurrent/LinkedBlockingQueue.java
diffstat 1 files changed, 12 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java	Wed Aug 26 12:17:29 2009 +0800
+++ b/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java	Tue Aug 25 19:19:42 2009 -0700
@@ -766,19 +766,21 @@
         }
 
         /**
-         * Unlike other traversal methods, iterators need to handle:
+         * Returns the next live successor of p, or null if no such.
+         *
+         * Unlike other traversal methods, iterators need to handle both:
          * - dequeued nodes (p.next == p)
-         * - interior removed nodes (p.item == null)
+         * - (possibly multiple) interior removed nodes (p.item == null)
          */
         private Node<E> nextNode(Node<E> p) {
-            Node<E> s = p.next;
-            if (p == s)
-                return head.next;
-            // Skip over removed nodes.
-            // May be necessary if multiple interior Nodes are removed.
-            while (s != null && s.item == null)
-                s = s.next;
-            return s;
+            for (;;) {
+                Node<E> s = p.next;
+                if (s == p)
+                    return head.next;
+                if (s == null || s.item != null)
+                    return s;
+                p = s;
+            }
         }
 
         public E next() {