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.61 by jsr166, Mon Nov 2 00:28:28 2009 UTC vs.
Revision 1.64 by jsr166, Mon Nov 2 06:12:02 2009 UTC

# Line 479 | Line 479 | public class LinkedTransferQueue<E> exte
479      }
480  
481      /*
482 <     * Possible values for "how" argument in xfer method. Beware that
483 <     * the order of assigned numerical values matters.
482 >     * Possible values for "how" argument in xfer method.
483       */
484      private static final int NOW     = 0; // for untimed poll, tryTransfer
485      private static final int ASYNC   = 1; // for offer, put, add
# Line 537 | Line 536 | public class LinkedTransferQueue<E> exte
536                  p = (p != n) ? n : (h = head); // Use head if p offlist
537              }
538  
539 <            if (how >= ASYNC) {               // No matches available
539 >            if (how != NOW) {                 // No matches available
540                  if (s == null)
541                      s = new Node(e, haveData);
542                  Node pred = tryAppend(s, haveData);
543                  if (pred == null)
544                      continue retry;           // lost race vs opposite mode
545 <                if (how >= SYNC)
546 <                    return awaitMatch(s, pred, e, how, nanos);
545 >                if (how != ASYNC)
546 >                    return awaitMatch(s, pred, e, (how == TIMEOUT), nanos);
547              }
548              return e; // not waiting
549          }
# Line 593 | Line 592 | public class LinkedTransferQueue<E> exte
592       * predecessor, or null if unknown (the null case does not occur
593       * in any current calls but may in possible future extensions)
594       * @param e the comparison value for checking match
595 <     * @param how either SYNC or TIMEOUT
595 >     * @param timed if true, wait only until timeout elapses
596       * @param nanos timeout value
597       * @return matched item, or e if unmatched on interrupt or timeout
598       */
599 <    private E awaitMatch(Node s, Node pred, E e, int how, long nanos) {
600 <        long lastTime = (how == TIMEOUT) ? System.nanoTime() : 0L;
599 >    private E awaitMatch(Node s, Node pred, E e, boolean timed, long nanos) {
600 >        long lastTime = timed ? System.nanoTime() : 0L;
601          Thread w = Thread.currentThread();
602          int spins = -1; // initialized after first item and cancel checks
603          ThreadLocalRandom randomYields = null; // bound if needed
# Line 610 | Line 609 | public class LinkedTransferQueue<E> exte
609                  s.forgetContents();           // avoid garbage
610                  return this.<E>cast(item);
611              }
612 <            if ((w.isInterrupted() || (how == TIMEOUT && nanos <= 0)) &&
612 >            if ((w.isInterrupted() || (timed && nanos <= 0)) &&
613                      s.casItem(e, s)) {       // cancel
614                  unsplice(pred, s);
615                  return e;
# Line 629 | Line 628 | public class LinkedTransferQueue<E> exte
628              else if (s.waiter == null) {
629                  s.waiter = w;                 // request unpark then recheck
630              }
631 <            else if (how == TIMEOUT) {
631 >            else if (timed) {
632                  long now = System.nanoTime();
633                  if ((nanos -= now - lastTime) > 0)
634                      LockSupport.parkNanos(this, nanos);
# Line 683 | Line 682 | public class LinkedTransferQueue<E> exte
682      /* -------------- Traversal methods -------------- */
683  
684      /**
685 +     * Returns the successor of p, or the head node if p.next has been
686 +     * linked to self, which will only be true if traversing with a
687 +     * stale pointer that is now off the list.
688 +     */
689 +    final Node succ(Node p) {
690 +        Node next = p.next;
691 +        return (p == next) ? head : next;
692 +    }
693 +
694 +    /**
695       * Returns the first unmatched node of the given mode, or null if
696       * none.  Used by methods isEmpty, hasWaitingConsumer.
697       */
698 <    private Node firstOfMode(boolean data) {
699 <        for (Node p = head; p != null; ) {
698 >    private Node firstOfMode(boolean isData) {
699 >        for (Node p = head; p != null; p = succ(p)) {
700              if (!p.isMatched())
701 <                return (p.isData == data) ? p : null;
693 <            Node n = p.next;
694 <            p = (n != p) ? n : head;
701 >                return (p.isData == isData) ? p : null;
702          }
703          return null;
704      }
# Line 701 | Line 708 | public class LinkedTransferQueue<E> exte
708       * null if none.  Used by peek.
709       */
710      private E firstDataItem() {
711 <        for (Node p = head; p != null; ) {
705 <            boolean isData = p.isData;
711 >        for (Node p = head; p != null; p = succ(p)) {
712              Object item = p.item;
713 <            if (item != p && (item != null) == isData)
714 <                return isData ? this.<E>cast(item) : null;
715 <            Node n = p.next;
716 <            p = (n != p) ? n : head;
713 >            if (p.isData) {
714 >                if (item != null && item != p)
715 >                    return this.<E>cast(item);
716 >            }
717 >            else if (item == null)
718 >                return null;
719          }
720          return null;
721      }
# Line 748 | Line 756 | public class LinkedTransferQueue<E> exte
756          private void advance(Node prev) {
757              lastPred = lastRet;
758              lastRet = prev;
759 <            Node p;
760 <            if (prev == null || (p = prev.next) == prev)
753 <                p = head;
754 <            while (p != null) {
759 >            for (Node p = (prev == null) ? head : succ(prev);
760 >                 p != null; p = succ(p)) {
761                  Object item = p.item;
762                  if (p.isData) {
763                      if (item != null && item != p) {
# Line 762 | Line 768 | public class LinkedTransferQueue<E> exte
768                  }
769                  else if (item == null)
770                      break;
765                Node n = p.next;
766                p = (n != p) ? n : head;
771              }
772              nextNode = null;
773          }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines