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

Comparing jsr166/src/main/java/util/concurrent/ConcurrentLinkedDeque.java (file contents):
Revision 1.16 by jsr166, Mon Sep 20 20:59:44 2010 UTC vs.
Revision 1.17 by jsr166, Mon Sep 20 23:16:26 2010 UTC

# Line 557 | Line 557 | public class ConcurrentLinkedDeque<E>
557       * Guarantees that any node which was unlinked before a call to
558       * this method will be unreachable from head after it returns.
559       * Does not guarantee to eliminate slack, only that head will
560 <     * point to a node that was active when this method was invoked.
560 >     * point to a node that was active while this method was running.
561       */
562      private final void updateHead() {
563 <        // We need to ensure head either already points to an active
564 <        // node, or that we or another thread updates it using casHead.
565 <        Node<E> h = head, p;
566 <        if (h.item == null && (p = h.prev) != null)
567 <            fullUpdateHead(h, p);
568 <    }
569 <
570 <    private final void fullUpdateHead(Node<E> h, Node<E> p) {
571 <        for (Node<E> q;;) {
572 <            if ((q = p.prev) == null ||
573 <                (q = (p = q).prev) == null) {
574 <                // It is possible that p is PREV_TERMINATOR,
575 <                // but if so, the CAS is guaranteed to fail.
576 <                casHead(h, p);
577 <                // If the CAS failed, someone else did our job for us.
578 <                return;
563 >        // Either head already points to an active node, or we keep
564 >        // trying to cas it to the first node until it does.
565 >        Node<E> h, p, q;
566 >        restartFromHead:
567 >        while ((h = head).item == null && (p = h.prev) != null) {
568 >            for (;;) {
569 >                if ((q = p.prev) == null ||
570 >                    (q = (p = q).prev) == null) {
571 >                    // It is possible that p is PREV_TERMINATOR,
572 >                    // but if so, the CAS is guaranteed to fail.
573 >                    if (casHead(h, p))
574 >                        return;
575 >                    else
576 >                        continue restartFromHead;
577 >                }
578 >                else if (h != head)
579 >                    continue restartFromHead;
580 >                else
581 >                    p = q;
582              }
580            else if (h != head)
581                return;
582            else
583                p = q;
583          }
584      }
585  
# Line 588 | Line 587 | public class ConcurrentLinkedDeque<E>
587       * Guarantees that any node which was unlinked before a call to
588       * this method will be unreachable from tail after it returns.
589       * Does not guarantee to eliminate slack, only that tail will
590 <     * point to a node that was active when this method was invoked.
590 >     * point to a node that was active while this method was running.
591       */
592      private final void updateTail() {
593 <        // We need to ensure tail either already points to an active
594 <        // node, or that we or another thread updates it using casTail.
595 <        Node<E> t = tail, p;
596 <        if (t.item == null && (p = t.next) != null)
597 <            fullUpdateTail(t, p);
598 <    }
599 <
600 <    private final void fullUpdateTail(Node<E> t, Node<E> p) {
601 <        for (Node<E> q;;) {
602 <            if ((q = p.next) == null ||
603 <                (q = (p = q).next) == null) {
604 <                // It is possible that p is PREV_TERMINATOR,
605 <                // but if so, the CAS is guaranteed to fail.
606 <                casTail(t, p);
607 <                // If the CAS failed, someone else did our job for us.
608 <                return;
593 >        // Either tail already points to an active node, or we keep
594 >        // trying to cas it to the last node until it does.
595 >        Node<E> t, p, q;
596 >        restartFromTail:
597 >        while ((t = tail).item == null && (p = t.next) != null) {
598 >            for (;;) {
599 >                if ((q = p.next) == null ||
600 >                    (q = (p = q).next) == null) {
601 >                    // It is possible that p is NEXT_TERMINATOR,
602 >                    // but if so, the CAS is guaranteed to fail.
603 >                    if (casTail(t, p))
604 >                        return;
605 >                    else
606 >                        continue restartFromTail;
607 >                }
608 >                else if (t != tail)
609 >                    continue restartFromTail;
610 >                else
611 >                    p = q;
612              }
611            else if (t != tail)
612                return;
613            else
614                p = q;
613          }
614      }
615  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines