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.57 by jsr166, Wed Oct 28 09:28:30 2009 UTC vs.
Revision 1.60 by dl, Fri Oct 30 12:06:31 2009 UTC

# Line 414 | Line 414 | public class LinkedTransferQueue<E> exte
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 +        /**
424           * Returns true if a node with the given mode cannot be
425           * appended to this node because this node is unmatched and
426           * has opposite data mode.
# 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 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