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

Comparing jsr166/src/main/java/util/concurrent/ArrayBlockingQueue.java (file contents):
Revision 1.92 by jsr166, Sat Jul 16 23:15:46 2011 UTC vs.
Revision 1.93 by jsr166, Sun Jul 17 13:05:58 2011 UTC

# Line 766 | Line 766 | public class ArrayBlockingQueue<E> exten
766          int cycles = 0;
767  
768          /** Linked list of weak iterator references */
769 <        private Node head = null;
769 >        private Node head;
770  
771          /** Used to expunge stale iterators */
772          private Node sweeper = null;
# Line 774 | Line 774 | public class ArrayBlockingQueue<E> exten
774          private static final int SHORT_SWEEP_PROBES = 4;
775          private static final int LONG_SWEEP_PROBES = 16;
776  
777 +        Itrs(Itr initial) {
778 +            register(initial);
779 +        }
780 +
781          /**
782           * Sweeps itrs, looking for and expunging stale iterators.
783           * If at least one was found, tries harder to find more.
# Line 783 | Line 787 | public class ArrayBlockingQueue<E> exten
787           */
788          void doSomeSweeping(boolean tryHarder) {
789              assert lock.getHoldCount() == 1;
790 +            assert head != null;
791              int probes = tryHarder ? LONG_SWEEP_PROBES : SHORT_SWEEP_PROBES;
792              Node o, p;
793              final Node sweeper = this.sweeper;
794 +            boolean passedGo;   // to limit search to one full sweep
795  
796 <            if (sweeper != null && sweeper.get() != null) {
791 <                o = sweeper;
792 <                p = o.next;
793 <            } else {
796 >            if (sweeper == null) {
797                  o = null;
798                  p = head;
799 +                passedGo = true;
800 +            } else {
801 +                o = sweeper;
802 +                p = o.next;
803 +                passedGo = false;
804              }
805  
806 <            for (; p != null && probes > 0; probes--) {
806 >            for (; probes > 0; probes--) {
807 >                if (p == null) {
808 >                    if (passedGo)
809 >                        break;
810 >                    o = null;
811 >                    p = head;
812 >                    passedGo = true;
813 >                }
814                  final Itr it = p.get();
815                  final Node next = p.next;
816                  if (it == null || it.isDetached()) {
# Line 804 | Line 819 | public class ArrayBlockingQueue<E> exten
819                      // unlink p
820                      p.clear();
821                      p.next = null;
822 <                    if (o == null)
822 >                    if (o == null) {
823                          head = next;
824 +                        if (next == null) {
825 +                            // We've run out of iterators to track; retire
826 +                            itrs = null;
827 +                            return;
828 +                        }
829 +                    }
830                      else
831                          o.next = next;
832                  } else {
# Line 813 | Line 834 | public class ArrayBlockingQueue<E> exten
834                  }
835                  p = next;
836              }
816            if (head == null)   // no more iterators to track
817                itrs = null;
837  
838              this.sweeper = (p == null) ? null : o;
839          }
# Line 858 | Line 877 | public class ArrayBlockingQueue<E> exten
877  
878          /**
879           * Called whenever an interior remove (not at takeIndex) occured.
880 +         *
881 +         * Notifies all iterators, and expunges any that are now stale.
882           */
883          void removedAt(int removedIndex) {
884              for (Node o = null, p = head; p != null;) {
# Line 981 | Line 1002 | public class ArrayBlockingQueue<E> exten
1002                      nextItem = itemAt(nextIndex = takeIndex);
1003                      cursor = incCursor(takeIndex);
1004                      if (itrs == null) {
1005 <                        itrs = new Itrs();
985 <                        itrs.register(this);
1005 >                        itrs = new Itrs(this);
1006                      } else {
1007                          itrs.register(this); // in this order
1008                          itrs.doSomeSweeping(false);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines