[cvs] / jsr166 / src / main / java / util / concurrent / LinkedTransferQueue.java Repository:
ViewVC logotype

Diff of /jsr166/src/main/java/util/concurrent/LinkedTransferQueue.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.136, Sat Jan 7 20:07:49 2017 UTC revision 1.137, Sat Jan 7 21:49:33 2017 UTC
# Line 560  Line 560 
560          return false;          return false;
561      }      }
562    
563      /*      /**
564       * Possible values for "how" argument in xfer method.       * 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      private static final int NOW   = 0; // for untimed poll, tryTransfer
589      private static final int ASYNC = 1; // for offer, put, add      private static final int ASYNC = 1; // for offer, put, add
590      private static final int SYNC  = 2; // for transfer, take      private static final int SYNC  = 2; // for transfer, take
# Line 1450  Line 1472 
1472       * @return {@code true} if this queue changed as a result of the call       * @return {@code true} if this queue changed as a result of the call
1473       */       */
1474      public boolean remove(Object o) {      public boolean remove(Object o) {
1475          if (o == null)          if (o == null) return false;
             return false;  
1476          restartFromHead: for (;;) {          restartFromHead: for (;;) {
1477              for (Node p = head, c = p, pred = null, q; p != null; ) {              for (Node p = head, pred = null; p != null; ) {
1478                  final Object item; boolean pAlive;                  Node q = p.next;
1479                  if (pAlive = ((item = p.item) != null && p.isData)) {                  final Object item;
1480                    if ((item = p.item) != null) {
1481                        if (p.isData) {
1482                      if (o.equals(item) && p.tryMatchData()) {                      if (o.equals(item) && p.tryMatchData()) {
1483                          if ((q = p.next) == null) q = p;                              skipDeadNodes(pred, p, p, q);
                         if (c != q) tryCasSuccessor(pred, c, q);  
1484                          return true;                          return true;
1485                      }                      }
1486                            pred = p; p = q; continue;
1487                  }                  }
1488                  else if (!p.isData && item == null)                  }
1489                    else if (!p.isData)
1490                      break;                      break;
1491                  if ((c != p && !tryCasSuccessor(pred, c, c = p)) || pAlive) {                  for (Node c = p;;) {
1492                      pred = p;                      if ((q = p.next) == null || !q.isMatched()) {
1493                      c = p = p.next;                          pred = skipDeadNodes(pred, c, p, q); p = q; break;
1494                        }
1495                        if (p == (p = q)) continue restartFromHead;
1496                  }                  }
                 else if (p == (p = p.next))  
                     continue restartFromHead;  
1497              }              }
1498              return false;              return false;
1499          }          }
# Line 1484  Line 1508 
1508       * @return {@code true} if this queue contains the specified element       * @return {@code true} if this queue contains the specified element
1509       */       */
1510      public boolean contains(Object o) {      public boolean contains(Object o) {
1511          if (o == null)          if (o == null) return false;
             return false;  
1512          restartFromHead: for (;;) {          restartFromHead: for (;;) {
1513              for (Node p = head, c = p, pred = null; p != null; ) {              for (Node p = head, pred = null; p != null; ) {
1514                  final Object item; final boolean pAlive;                  Node q = p.next;
1515                  if (pAlive = ((item = p.item) != null && p.isData)) {                  final Object item;
1516                    if ((item = p.item) != null) {
1517                        if (p.isData) {
1518                      if (o.equals(item))                      if (o.equals(item))
1519                          return true;                          return true;
1520                            pred = p; p = q; continue;
1521                  }                  }
1522                  else if (!p.isData && item == null)                  }
1523                    else if (!p.isData)
1524                      break;                      break;
1525                  if ((c != p && !tryCasSuccessor(pred, c, c = p)) || pAlive) {                  for (Node c = p;;) {
1526                      pred = p;                      if ((q = p.next) == null || !q.isMatched()) {
1527                      c = p = p.next;                          pred = skipDeadNodes(pred, c, p, q); p = q; break;
1528                        }
1529                        if (p == (p = q)) continue restartFromHead;
1530                  }                  }
                 else if (p == (p = p.next))  
                     continue restartFromHead;  
1531              }              }
1532              return false;              return false;
1533          }          }
# Line 1632  Line 1659 
1659       */       */
1660      @SuppressWarnings("unchecked")      @SuppressWarnings("unchecked")
1661      void forEachFrom(Consumer<? super E> action, Node p) {      void forEachFrom(Consumer<? super E> action, Node p) {
1662          for (Node c = p, pred = null; p != null; ) {          for (Node pred = null; p != null; ) {
1663              final Object item; final boolean pAlive;              Node q = p.next;
1664              if (pAlive = ((item = p.item) != null && p.isData))              final Object item;
1665                if ((item = p.item) != null) {
1666                    if (p.isData) {
1667                  action.accept((E) item);                  action.accept((E) item);
1668              else if (!p.isData && item == null)                      pred = p; p = q; continue;
1669                    }
1670                }
1671                else if (!p.isData)
1672                  break;                  break;
1673              if ((c != p && !tryCasSuccessor(pred, c, c = p)) || pAlive) {              for (Node c = p;;) {
1674                  pred = p;                  if ((q = p.next) == null || !q.isMatched()) {
1675                  c = p = p.next;                      pred = skipDeadNodes(pred, c, p, q); p = q; break;
1676              }              }
1677              else if (p == (p = p.next)) {                  if (p == (p = q)) { pred = null; p = head; break; }
                 pred = null;  
                 c = p = head;  
1678              }              }
1679          }          }
1680      }      }

Legend:
Removed from v.1.136  
changed lines
  Added in v.1.137

Doug Lea
ViewVC Help
Powered by ViewVC 1.0.8