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.14 by jsr166, Thu Mar 19 05:10:42 2009 UTC vs.
Revision 1.15 by dl, Wed Mar 25 13:43:42 2009 UTC

# Line 116 | Line 116 | public class LinkedTransferQueue<E> exte
116              nextUpdater = AtomicReferenceFieldUpdater.newUpdater
117              (QNode.class, QNode.class, "next");
118  
119 <        boolean casNext(QNode cmp, QNode val) {
119 >        final boolean casNext(QNode cmp, QNode val) {
120              return nextUpdater.compareAndSet(this, cmp, val);
121          }
122 +
123 +        final void clearNext() {
124 +            nextUpdater.lazySet(this, this);
125 +        }
126 +
127      }
128  
129      /**
# Line 151 | Line 156 | public class LinkedTransferQueue<E> exte
156       */
157      private boolean advanceHead(QNode h, QNode nh) {
158          if (h == head.get() && head.compareAndSet(h, nh)) {
159 <            h.next = h; // forget old next
159 >            h.clearNext(); // forget old next
160              return true;
161          }
162          return false;
# Line 344 | Line 349 | public class LinkedTransferQueue<E> exte
349              if (w != Thread.currentThread())
350                  LockSupport.unpark(w);
351          }
352 +
353 +        if (pred == null)
354 +            return;
355 +
356          /*
357           * At any given time, exactly one node on list cannot be
358           * deleted -- the last inserted node. To accommodate this, if
# Line 442 | Line 451 | public class LinkedTransferQueue<E> exte
451          return true;
452      }
453  
454 +    public boolean add(E e) {
455 +        if (e == null) throw new NullPointerException();
456 +        xfer(e, NOWAIT, 0);
457 +        return true;
458 +    }
459 +
460      public void transfer(E e) throws InterruptedException {
461          if (e == null) throw new NullPointerException();
462          if (xfer(e, WAIT, 0) == null) {
# Line 538 | Line 553 | public class LinkedTransferQueue<E> exte
553                          return h;
554                  }
555              }
556 +            reclean();
557          }
558      }
559  
# Line 554 | Line 570 | public class LinkedTransferQueue<E> exte
570       * if subsequently removed.
571       */
572      class Itr implements Iterator<E> {
573 <        QNode nextNode;    // Next node to return next
574 <        QNode currentNode; // last returned node, for remove()
575 <        QNode prevNode;    // predecessor of last returned node
573 >        QNode next;        // node to return next
574 >        QNode pnext;       // predecessor of next
575 >        QNode snext;       // successor of next
576 >        QNode curr;        // last returned node, for remove()
577 >        QNode pcurr;       // predecessor of curr, for remove()
578          E nextItem;        // Cache of next item, once commited to in next
579  
580          Itr() {
581 <            nextNode = traversalHead();
564 <            advance();
581 >            findNext();
582          }
583  
584 <        E advance() {
585 <            prevNode = currentNode;
586 <            currentNode = nextNode;
587 <            E x = nextItem;
571 <
572 <            QNode p = nextNode.next;
584 >        /**
585 >         * Ensure next points to next valid node, or null if none.
586 >         */
587 >        void findNext() {
588              for (;;) {
589 <                if (p == null || !p.isData) {
590 <                    nextNode = null;
591 <                    nextItem = null;
592 <                    return x;
589 >                QNode pred = pnext;
590 >                QNode q = next;
591 >                if (pred == null || pred == q) {
592 >                    pred = traversalHead();
593 >                    q = pred.next;
594 >                }
595 >                if (q == null || !q.isData) {
596 >                    next = null;
597 >                    return;
598 >                }
599 >                Object x = q.get();
600 >                QNode s = q.next;
601 >                if (x != null && q != x && q != s) {
602 >                    nextItem = (E)x;
603 >                    snext = s;
604 >                    pnext = pred;
605 >                    next = q;
606 >                    return;
607                  }
608 <                Object item = p.get();
609 <                if (item != p && item != null) {
581 <                    nextNode = p;
582 <                    nextItem = (E)item;
583 <                    return x;
584 <                }
585 <                prevNode = p;
586 <                p = p.next;
608 >                pnext = q;
609 >                next = s;
610              }
611          }
612  
613          public boolean hasNext() {
614 <            return nextNode != null;
614 >            return next != null;
615          }
616  
617          public E next() {
618 <            if (nextNode == null) throw new NoSuchElementException();
619 <            return advance();
618 >            if (next == null) throw new NoSuchElementException();
619 >            pcurr = pnext;
620 >            curr = next;
621 >            pnext = next;
622 >            next = snext;
623 >            E x = nextItem;
624 >            findNext();
625 >            return x;
626          }
627  
628          public void remove() {
629 <            QNode p = currentNode;
630 <            QNode prev = prevNode;
602 <            if (prev == null || p == null)
629 >            QNode p = curr;
630 >            if (p == null)
631                  throw new IllegalStateException();
632              Object x = p.get();
633              if (x != null && x != p && p.compareAndSet(x, p))
634 <                clean(prev, p);
634 >                clean(pcurr, p);
635          }
636      }
637  
# Line 692 | Line 720 | public class LinkedTransferQueue<E> exte
720          return Integer.MAX_VALUE;
721      }
722  
723 +    public boolean remove(Object o) {
724 +        if (o == null)
725 +            return false;
726 +        for (;;) {
727 +            QNode pred = traversalHead();
728 +            for (;;) {
729 +                QNode q = pred.next;
730 +                if (q == null || !q.isData)
731 +                    return false;
732 +                if (q == pred) // restart
733 +                    break;
734 +                Object x = q.get();
735 +                if (x != null && x != q && o.equals(x) &&
736 +                    q.compareAndSet(x, q)) {
737 +                    clean(pred, q);
738 +                    return true;
739 +                }
740 +                pred = q;
741 +            }
742 +        }
743 +    }
744 +
745      /**
746       * Save the state to a stream (that is, serialize it).
747       *

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines