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

Comparing jsr166/src/main/java/util/concurrent/LinkedTransferQueue.java (file contents):
Revision 1.136 by jsr166, Sat Jan 7 20:07:49 2017 UTC vs.
Revision 1.137 by jsr166, Sat Jan 7 21:49:33 2017 UTC

# Line 560 | Line 560 | public class LinkedTransferQueue<E> exte
560          return false;
561      }
562  
563 <    /*
564 <     * Possible values for "how" argument in xfer method.
565 <     */
563 >    /**
564 >     * Collapse dead (matched) nodes between pred and q.
565 >     * @param pred the last known live node, or null if none
566 >     * @param c the first dead node
567 >     * @param p the last dead node
568 >     * @param q p.next: the next live node, or null if at end
569 >     * @return either old pred or p if pred dead or CAS failed
570 >     */
571 >    private Node skipDeadNodes(Node pred, Node c, Node p, Node q) {
572 >        // assert pred != c;
573 >        // assert p != q;
574 >        // assert c.isMatched();
575 >        // assert p.isMatched();
576 >        if (q == null) {
577 >            // Never unlink trailing node.
578 >            if (c == p) return pred;
579 >            q = p;
580 >        }
581 >        return (tryCasSuccessor(pred, c, q)
582 >                && (pred == null || !pred.isMatched()))
583 >            ? pred : p;
584 >    }
585 >
586 >    /* Possible values for "how" argument in xfer method. */
587 >
588      private static final int NOW   = 0; // for untimed poll, tryTransfer
589      private static final int ASYNC = 1; // for offer, put, add
590      private static final int SYNC  = 2; // for transfer, take
# Line 1450 | Line 1472 | public class LinkedTransferQueue<E> exte
1472       * @return {@code true} if this queue changed as a result of the call
1473       */
1474      public boolean remove(Object o) {
1475 <        if (o == null)
1454 <            return false;
1475 >        if (o == null) return false;
1476          restartFromHead: for (;;) {
1477 <            for (Node p = head, c = p, pred = null, q; p != null; ) {
1478 <                final Object item; boolean pAlive;
1479 <                if (pAlive = ((item = p.item) != null && p.isData)) {
1480 <                    if (o.equals(item) && p.tryMatchData()) {
1481 <                        if ((q = p.next) == null) q = p;
1482 <                        if (c != q) tryCasSuccessor(pred, c, q);
1483 <                        return true;
1477 >            for (Node p = head, pred = null; p != null; ) {
1478 >                Node q = p.next;
1479 >                final Object item;
1480 >                if ((item = p.item) != null) {
1481 >                    if (p.isData) {
1482 >                        if (o.equals(item) && p.tryMatchData()) {
1483 >                            skipDeadNodes(pred, p, p, q);
1484 >                            return true;
1485 >                        }
1486 >                        pred = p; p = q; continue;
1487                      }
1488                  }
1489 <                else if (!p.isData && item == null)
1489 >                else if (!p.isData)
1490                      break;
1491 <                if ((c != p && !tryCasSuccessor(pred, c, c = p)) || pAlive) {
1492 <                    pred = p;
1493 <                    c = p = p.next;
1491 >                for (Node c = p;;) {
1492 >                    if ((q = p.next) == null || !q.isMatched()) {
1493 >                        pred = skipDeadNodes(pred, c, p, q); p = q; break;
1494 >                    }
1495 >                    if (p == (p = q)) continue restartFromHead;
1496                  }
1471                else if (p == (p = p.next))
1472                    continue restartFromHead;
1497              }
1498              return false;
1499          }
# Line 1484 | Line 1508 | public class LinkedTransferQueue<E> exte
1508       * @return {@code true} if this queue contains the specified element
1509       */
1510      public boolean contains(Object o) {
1511 <        if (o == null)
1488 <            return false;
1511 >        if (o == null) return false;
1512          restartFromHead: for (;;) {
1513 <            for (Node p = head, c = p, pred = null; p != null; ) {
1514 <                final Object item; final boolean pAlive;
1515 <                if (pAlive = ((item = p.item) != null && p.isData)) {
1516 <                    if (o.equals(item))
1517 <                        return true;
1513 >            for (Node p = head, pred = null; p != null; ) {
1514 >                Node q = p.next;
1515 >                final Object item;
1516 >                if ((item = p.item) != null) {
1517 >                    if (p.isData) {
1518 >                        if (o.equals(item))
1519 >                            return true;
1520 >                        pred = p; p = q; continue;
1521 >                    }
1522                  }
1523 <                else if (!p.isData && item == null)
1523 >                else if (!p.isData)
1524                      break;
1525 <                if ((c != p && !tryCasSuccessor(pred, c, c = p)) || pAlive) {
1526 <                    pred = p;
1527 <                    c = p = p.next;
1525 >                for (Node c = p;;) {
1526 >                    if ((q = p.next) == null || !q.isMatched()) {
1527 >                        pred = skipDeadNodes(pred, c, p, q); p = q; break;
1528 >                    }
1529 >                    if (p == (p = q)) continue restartFromHead;
1530                  }
1502                else if (p == (p = p.next))
1503                    continue restartFromHead;
1531              }
1532              return false;
1533          }
# Line 1632 | Line 1659 | public class LinkedTransferQueue<E> exte
1659       */
1660      @SuppressWarnings("unchecked")
1661      void forEachFrom(Consumer<? super E> action, Node p) {
1662 <        for (Node c = p, pred = null; p != null; ) {
1663 <            final Object item; final boolean pAlive;
1664 <            if (pAlive = ((item = p.item) != null && p.isData))
1665 <                action.accept((E) item);
1666 <            else if (!p.isData && item == null)
1662 >        for (Node pred = null; p != null; ) {
1663 >            Node q = p.next;
1664 >            final Object item;
1665 >            if ((item = p.item) != null) {
1666 >                if (p.isData) {
1667 >                    action.accept((E) item);
1668 >                    pred = p; p = q; continue;
1669 >                }
1670 >            }
1671 >            else if (!p.isData)
1672                  break;
1673 <            if ((c != p && !tryCasSuccessor(pred, c, c = p)) || pAlive) {
1674 <                pred = p;
1675 <                c = p = p.next;
1676 <            }
1677 <            else if (p == (p = p.next)) {
1646 <                pred = null;
1647 <                c = p = head;
1673 >            for (Node c = p;;) {
1674 >                if ((q = p.next) == null || !q.isMatched()) {
1675 >                    pred = skipDeadNodes(pred, c, p, q); p = q; break;
1676 >                }
1677 >                if (p == (p = q)) { pred = null; p = head; break; }
1678              }
1679          }
1680      }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines