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.54 by jsr166, Tue Oct 27 23:14:08 2009 UTC vs.
Revision 1.60 by dl, Fri Oct 30 12:06:31 2009 UTC

# Line 373 | Line 373 | public class LinkedTransferQueue<E> exte
373          }
374  
375          final boolean casItem(Object cmp, Object val) {
376 <            assert cmp.getClass() != Node.class;
376 >            assert cmp == null || cmp.getClass() != Node.class;
377              return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
378          }
379  
# Line 410 | Line 410 | public class LinkedTransferQueue<E> exte
410           */
411          final boolean isMatched() {
412              Object x = item;
413 <            return x == this || (x != null) != isData;
413 >            return (x == this) || ((x == null) == isData);
414 >        }
415 >
416 >        /**
417 >         * Returns true if this is an unmatched request node.
418 >         */
419 >        final boolean isUnmatchedRequest() {
420 >            return !isData && item == null;
421          }
422  
423          /**
# Line 428 | Line 435 | public class LinkedTransferQueue<E> exte
435           * Tries to artificially match a data node -- used by remove.
436           */
437          final boolean tryMatchData() {
438 +            assert isData;
439              Object x = item;
440              if (x != null && x != this && casItem(x, null)) {
441                  LockSupport.unpark(waiter);
# Line 479 | Line 487 | public class LinkedTransferQueue<E> exte
487      private static final int SYNC    = 2; // for transfer, take
488      private static final int TIMEOUT = 3; // for timed poll, tryTransfer
489  
490 +    @SuppressWarnings("unchecked")
491 +    static <E> E cast(Object item) {
492 +        assert item == null || item.getClass() != Node.class;
493 +        return (E) item;
494 +    }
495 +
496      /**
497       * Implements all queuing methods. See above for explanation.
498       *
# Line 683 | Line 697 | public class LinkedTransferQueue<E> exte
697          return null;
698      }
699  
686    @SuppressWarnings("unchecked")
687    static <E> E cast(Object item) {
688        assert item.getClass() != Node.class;
689        return (E) item;
690    }
691
700      /**
701       * Returns the item in the first unmatched node with isData; or
702       * null if none.  Used by peek.
# Line 733 | Line 741 | public class LinkedTransferQueue<E> exte
741          private Node<E> nextNode;   // next node to return item for
742          private E nextItem;         // the corresponding item
743          private Node<E> lastRet;    // last returned node, to support remove
744 +        private Node<E> lastPred;   // predecessor to unlink lastRet
745  
746          /**
747           * Moves to next node after prev, or first node if prev null.
748           */
749          private void advance(Node<E> prev) {
750 +            lastPred = lastRet;
751              lastRet = prev;
752              Node<E> p;
753              if (prev == null || (p = prev.next) == prev)
# Line 778 | Line 788 | public class LinkedTransferQueue<E> exte
788          public final void remove() {
789              Node<E> p = lastRet;
790              if (p == null) throw new IllegalStateException();
791 <            lastRet = null;
782 <            findAndRemoveNode(p);
791 >            findAndRemoveDataNode(lastPred, p);
792          }
793      }
794  
# Line 813 | Line 822 | public class LinkedTransferQueue<E> exte
822                      break;
823                  }
824                  if (oldpred == pred ||      // Already saved
825 <                    (oldpred == null && casCleanMe(null, pred)))
826 <                    break;                  // Postpone cleaning
825 >                    ((oldpred == null || oldpred.next == s) &&
826 >                     casCleanMe(oldpred, pred))) {
827 >                    break;
828 >                }
829              }
830          }
831      }
# Line 855 | Line 866 | public class LinkedTransferQueue<E> exte
866  
867      /**
868       * Main implementation of Iterator.remove(). Find
869 <     * and unsplice the given node.
869 >     * and unsplice the given data node.
870 >     * @param possiblePred possible predecessor of s
871 >     * @param s the node to remove
872       */
873 <    final void findAndRemoveNode(Node<E> s) {
873 >    final void findAndRemoveDataNode(Node<E> possiblePred, Node<E> s) {
874 >        assert s.isData;
875          if (s.tryMatchData()) {
876 <            Node<E> pred = null;
877 <            Node<E> p = head;
878 <            while (p != null) {
879 <                if (p == s) {
880 <                    unsplice(pred, p);
881 <                    break;
882 <                }
883 <                if (!p.isData && !p.isMatched())
884 <                    break;
885 <                pred = p;
886 <                if ((p = p.next) == pred) { // stale
887 <                    pred = null;
888 <                    p = head;
876 >            if (possiblePred != null && possiblePred.next == s)
877 >                unsplice(possiblePred, s); // was actual predecessor
878 >            else {
879 >                for (Node<E> pred = null, p = head; p != null; ) {
880 >                    if (p == s) {
881 >                        unsplice(pred, p);
882 >                        break;
883 >                    }
884 >                    if (p.isUnmatchedRequest())
885 >                        break;
886 >                    pred = p;
887 >                    if ((p = p.next) == pred) { // stale
888 >                        pred = null;
889 >                        p = head;
890 >                    }
891                  }
892              }
893          }
# Line 882 | Line 898 | public class LinkedTransferQueue<E> exte
898       */
899      private boolean findAndRemove(Object e) {
900          if (e != null) {
901 <            Node<E> pred = null;
886 <            Node<E> p = head;
887 <            while (p != null) {
901 >            for (Node<E> pred = null, p = head; p != null; ) {
902                  Object item = p.item;
903                  if (p.isData) {
904                      if (item != null && item != p && e.equals(item) &&
# Line 896 | Line 910 | public class LinkedTransferQueue<E> exte
910                  else if (item == null)
911                      break;
912                  pred = p;
913 <                if ((p = p.next) == pred) {
913 >                if ((p = p.next) == pred) { // stale
914                      pred = null;
915                      p = head;
916                  }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines