ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166y/LinkedTransferQueue.java
(Generate patch)

Comparing jsr166/src/jsr166y/LinkedTransferQueue.java (file contents):
Revision 1.68 by jsr166, Sun Nov 15 01:53:11 2009 UTC vs.
Revision 1.74 by jsr166, Wed Sep 1 21:43:08 2010 UTC

# Line 15 | Line 15 | import java.util.Iterator;
15   import java.util.NoSuchElementException;
16   import java.util.Queue;
17   import java.util.concurrent.locks.LockSupport;
18 +
19   /**
20   * An unbounded {@link TransferQueue} based on linked nodes.
21   * This queue orders elements FIFO (first-in-first-out) with respect
# Line 321 | Line 322 | public class LinkedTransferQueue<E> exte
322       * situations in which we cannot guarantee to make node s
323       * unreachable in this way: (1) If s is the trailing node of list
324       * (i.e., with null next), then it is pinned as the target node
325 <     * for appends, so can only be removed later when other nodes are
325 >     * for appends, so can only be removed later after other nodes are
326       * appended. (2) We cannot necessarily unlink s given a
327       * predecessor node that is matched (including the case of being
328       * cancelled): the predecessor may already be unspliced, in which
# Line 343 | Line 344 | public class LinkedTransferQueue<E> exte
344       * When these cases arise, rather than always retraversing the
345       * entire list to find an actual predecessor to unlink (which
346       * won't help for case (1) anyway), we record a conservative
347 <     * estimate of possible unsplice failures (in "sweepVotes).  We
347 >     * estimate of possible unsplice failures (in "sweepVotes").  We
348       * trigger a full sweep when the estimate exceeds a threshold
349       * indicating the maximum number of estimated removal failures to
350       * tolerate before sweeping through, unlinking cancelled nodes
# Line 422 | Line 423 | public class LinkedTransferQueue<E> exte
423          }
424  
425          final boolean casItem(Object cmp, Object val) {
426 <            assert cmp == null || cmp.getClass() != Node.class;
426 >            //            assert cmp == null || cmp.getClass() != Node.class;
427              return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
428          }
429  
# Line 446 | Line 447 | public class LinkedTransferQueue<E> exte
447          /**
448           * Sets item to self and waiter to null, to avoid garbage
449           * retention after matching or cancelling. Uses relaxed writes
450 <         * bacause order is already constrained in the only calling
450 >         * because order is already constrained in the only calling
451           * contexts: item is forgotten only after volatile/atomic
452           * mechanics that extract items.  Similarly, clearing waiter
453           * follows either CAS or return from park (if ever parked;
# Line 488 | Line 489 | public class LinkedTransferQueue<E> exte
489           * Tries to artificially match a data node -- used by remove.
490           */
491          final boolean tryMatchData() {
492 <            assert isData;
492 >            //            assert isData;
493              Object x = item;
494              if (x != null && x != this && casItem(x, null)) {
495                  LockSupport.unpark(waiter);
# Line 541 | Line 542 | public class LinkedTransferQueue<E> exte
542  
543      @SuppressWarnings("unchecked")
544      static <E> E cast(Object item) {
545 <        assert item == null || item.getClass() != Node.class;
545 >        //        assert item == null || item.getClass() != Node.class;
546          return (E) item;
547      }
548  
# Line 656 | Line 657 | public class LinkedTransferQueue<E> exte
657          for (;;) {
658              Object item = s.item;
659              if (item != e) {                  // matched
660 <                assert item != s;
660 >                //                assert item != s;
661                  s.forgetContents();           // avoid garbage
662                  return this.<E>cast(item);
663              }
# Line 876 | Line 877 | public class LinkedTransferQueue<E> exte
877      }
878  
879      /**
880 <     * Unlink matched nodes encountered in a traversal from head
880 >     * Unlinks matched nodes encountered in a traversal from head.
881       */
882      private void sweep() {
883 <        Node p = head, s, n;
884 <        while (p != null && (s = p.next) != null && (n = s.next) != null) {
885 <            if (p == s || s == n)
886 <                p = head; // stale
886 <            else if (s.isMatched())
887 <                p.casNext(s, n);
888 <            else
883 >        for (Node p = head, s, n; p != null && (s = p.next) != null; ) {
884 >            if (p == s)                    // stale
885 >                p = head;
886 >            else if (!s.isMatched())
887                  p = s;
888 +            else if ((n = s.next) == null) // trailing node is pinned
889 +                break;
890 +            else
891 +                p.casNext(s, n);
892          }
893      }
894  
# Line 1124 | Line 1126 | public class LinkedTransferQueue<E> exte
1126       * @return {@code true} if this queue contains no elements
1127       */
1128      public boolean isEmpty() {
1129 <        return firstOfMode(true) == null;
1129 >        for (Node p = head; p != null; p = succ(p)) {
1130 >            if (!p.isMatched())
1131 >                return !p.isData;
1132 >        }
1133 >        return true;
1134      }
1135  
1136      public boolean hasWaitingConsumer() {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines