--- jsr166/src/jsr166y/LinkedTransferQueue.java 2009/10/29 00:29:16 1.59 +++ jsr166/src/jsr166y/LinkedTransferQueue.java 2009/10/30 12:06:31 1.60 @@ -741,11 +741,13 @@ public class LinkedTransferQueue exte private Node nextNode; // next node to return item for private E nextItem; // the corresponding item private Node lastRet; // last returned node, to support remove + private Node lastPred; // predecessor to unlink lastRet /** * Moves to next node after prev, or first node if prev null. */ private void advance(Node prev) { + lastPred = lastRet; lastRet = prev; Node p; if (prev == null || (p = prev.next) == prev) @@ -786,8 +788,7 @@ public class LinkedTransferQueue exte public final void remove() { Node p = lastRet; if (p == null) throw new IllegalStateException(); - lastRet = null; - findAndRemoveDataNode(p); + findAndRemoveDataNode(lastPred, p); } } @@ -866,21 +867,27 @@ public class LinkedTransferQueue exte /** * Main implementation of Iterator.remove(). Find * and unsplice the given data node. + * @param possiblePred possible predecessor of s + * @param s the node to remove */ - final void findAndRemoveDataNode(Node s) { + final void findAndRemoveDataNode(Node possiblePred, Node s) { assert s.isData; if (s.tryMatchData()) { - for (Node pred = null, p = head; p != null; ) { - if (p == s) { - unsplice(pred, p); - break; - } - if (p.isUnmatchedRequest()) - break; - pred = p; - if ((p = p.next) == pred) { // stale - pred = null; - p = head; + if (possiblePred != null && possiblePred.next == s) + unsplice(possiblePred, s); // was actual predecessor + else { + for (Node pred = null, p = head; p != null; ) { + if (p == s) { + unsplice(pred, p); + break; + } + if (p.isUnmatchedRequest()) + break; + pred = p; + if ((p = p.next) == pred) { // stale + pred = null; + p = head; + } } } }