From dd70c1b8a983e86edff6bb148b0b191a509f5155 Mon Sep 17 00:00:00 2001 From: dl Date: Tue, 25 Aug 2009 19:19:42 -0700 Subject: [PATCH] 6871697: LinkedBlockingQueue Iterator/remove/poll race Summary: More checks for node.next == node Reviewed-by: martin, dholmes, chegar --- .../util/concurrent/LinkedBlockingQueue.java | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java b/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java index 10f2b6540..dc946786f 100644 --- a/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java +++ b/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java @@ -766,19 +766,21 @@ public class LinkedBlockingQueue extends AbstractQueue } /** - * 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 nextNode(Node p) { - Node 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 s = p.next; + if (s == p) + return head.next; + if (s == null || s.item != null) + return s; + p = s; + } } public E next() { -- GitLab