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.121 by jsr166, Wed Dec 28 18:07:18 2016 UTC vs.
Revision 1.122 by jsr166, Wed Dec 28 20:55:41 2016 UTC

# Line 544 | Line 544 | public class LinkedTransferQueue<E> exte
544          return SWEEPVOTES.compareAndSet(this, cmp, val);
545      }
546  
547 +    /**
548 +     * Tries to CAS pred.next (or head, if pred is null) from c to p.
549 +     */
550 +    private boolean tryCasSuccessor(Node pred, Node c, Node p) {
551 +        // assert c != p;
552 +        if (pred != null)
553 +            return pred.casNext(c, p);
554 +        if (casHead(c, p)) {
555 +            c.forgetNext();
556 +            return true;
557 +        }
558 +        return false;
559 +    }
560 +
561      /*
562       * Possible values for "how" argument in xfer method.
563       */
# Line 1426 | Line 1440 | public class LinkedTransferQueue<E> exte
1440          if (o == null)
1441              return false;
1442          restartFromHead: for (;;) {
1443 <            for (Node pred = null, p = head; p != null; ) {
1444 <                Object item = p.item;
1445 <                if (p.isData) {
1446 <                    if (item != null
1447 <                        && o.equals(item)
1448 <                        && p.tryMatchData()) {
1435 <                        unsplice(pred, p);
1443 >            for (Node p = head, c = p, pred = null, q; p != null; ) {
1444 >                final Object item; boolean pAlive;
1445 >                if (pAlive = (((item = p.item) != null) && p.isData)) {
1446 >                    if (o.equals(item) && p.tryMatchData()) {
1447 >                        if ((q = p.next) == null) q = p;
1448 >                        if (c != q) tryCasSuccessor(pred, c, q);
1449                          return true;
1450                      }
1451                  }
1452 <                else if (item == null)
1452 >                else if (!p.isData && item == null)
1453                      break;
1454 <                if ((pred = p) == (p = p.next))
1454 >                if (c != p && tryCasSuccessor(pred, c, p))
1455 >                    c = p;
1456 >                q = p.next;
1457 >                if (pAlive || c != p) {
1458 >                    pred = p;
1459 >                    p = c = q;
1460 >                }
1461 >                else if (p == (p = q))
1462                      continue restartFromHead;
1463              }
1464              return false;
# Line 1454 | Line 1474 | public class LinkedTransferQueue<E> exte
1474       * @return {@code true} if this queue contains the specified element
1475       */
1476      public boolean contains(Object o) {
1477 <        if (o != null) {
1478 <            for (Node p = head; p != null; ) {
1479 <                Object item = p.item;
1480 <                if (p.isData) {
1481 <                    if (item != null && o.equals(item))
1477 >        if (o == null)
1478 >            return false;
1479 >        restartFromHead: for (;;) {
1480 >            for (Node p = head, c = p, pred = null, q; p != null; ) {
1481 >                final Object item; final boolean pAlive;
1482 >                if (pAlive = (((item = p.item) != null) && p.isData)) {
1483 >                    if (o.equals(item))
1484                          return true;
1485                  }
1486 <                else if (item == null)
1486 >                else if (!p.isData && item == null)
1487                      break;
1488 <                if (p == (p = p.next))
1489 <                    p = head;
1488 >                if (c != p && tryCasSuccessor(pred, c, p))
1489 >                    c = p;
1490 >                q = p.next;
1491 >                if (pAlive || c != p) {
1492 >                    pred = p;
1493 >                    p = c = q;
1494 >                }
1495 >                else if (p == (p = q))
1496 >                    continue restartFromHead;
1497              }
1498 +            return false;
1499          }
1470        return false;
1500      }
1501  
1502      /**
# Line 1575 | Line 1604 | public class LinkedTransferQueue<E> exte
1604       */
1605      @SuppressWarnings("unchecked")
1606      void forEachFrom(Consumer<? super E> action, Node p) {
1607 <        while (p != null) {
1608 <            final Object item = p.item;
1609 <            if (p.isData) {
1610 <                if (item != null)
1611 <                    action.accept((E) item);
1583 <            }
1584 <            else if (item == null)
1607 >        for (Node c = p, pred = null, q; p != null; ) {
1608 >            final Object item; final boolean pAlive;
1609 >            if (pAlive = (((item = p.item) != null) && p.isData))
1610 >                action.accept((E) item);
1611 >            else if (!p.isData && item == null)
1612                  break;
1613 <            if (p == (p = p.next))
1614 <                p = head;
1613 >            if (c != p && tryCasSuccessor(pred, c, p))
1614 >                c = p;
1615 >            q = p.next;
1616 >            if (pAlive || c != p) {
1617 >                pred = p;
1618 >                p = c = q;
1619 >            }
1620 >            else if (p == (p = q)) {
1621 >                pred = null;
1622 >                c = p = head;
1623 >            }
1624          }
1625      }
1626  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines