--- jsr166/src/jsr166y/LinkedTransferQueue.java 2009/11/15 01:53:11 1.68 +++ jsr166/src/jsr166y/LinkedTransferQueue.java 2010/04/05 15:50:51 1.72 @@ -343,7 +343,7 @@ public class LinkedTransferQueue exte * When these cases arise, rather than always retraversing the * entire list to find an actual predecessor to unlink (which * won't help for case (1) anyway), we record a conservative - * estimate of possible unsplice failures (in "sweepVotes). We + * estimate of possible unsplice failures (in "sweepVotes"). We * trigger a full sweep when the estimate exceeds a threshold * indicating the maximum number of estimated removal failures to * tolerate before sweeping through, unlinking cancelled nodes @@ -876,17 +876,18 @@ public class LinkedTransferQueue exte } /** - * Unlink matched nodes encountered in a traversal from head + * Unlinks matched nodes encountered in a traversal from head. */ private void sweep() { - Node p = head, s, n; - while (p != null && (s = p.next) != null && (n = s.next) != null) { - if (p == s || s == n) - p = head; // stale - else if (s.isMatched()) - p.casNext(s, n); - else + for (Node p = head, s, n; p != null && (s = p.next) != null; ) { + if (p == s) // stale + p = head; + else if (!s.isMatched()) p = s; + else if ((n = s.next) == null) // trailing node is pinned + break; + else + p.casNext(s, n); } } @@ -1124,7 +1125,11 @@ public class LinkedTransferQueue exte * @return {@code true} if this queue contains no elements */ public boolean isEmpty() { - return firstOfMode(true) == null; + for (Node p = head; p != null; p = succ(p)) { + if (!p.isMatched()) + return !p.isData; + } + return true; } public boolean hasWaitingConsumer() {