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.15 by dl, Wed Mar 25 13:43:42 2009 UTC vs.
Revision 1.23 by jsr166, Thu Jul 23 23:07:57 2009 UTC

# Line 44 | Line 44 | import java.lang.reflect.*;
44   * @since 1.7
45   * @author Doug Lea
46   * @param <E> the type of elements held in this collection
47 *
47   */
48   public class LinkedTransferQueue<E> extends AbstractQueue<E>
49      implements TransferQueue<E>, java.io.Serializable {
# Line 81 | Line 80 | public class LinkedTransferQueue<E> exte
80       * seems not to vary with number of CPUs (beyond 2) so is just
81       * a constant.
82       */
83 <    static final int maxTimedSpins = (NCPUS < 2)? 0 : 32;
83 >    static final int maxTimedSpins = (NCPUS < 2) ? 0 : 32;
84  
85      /**
86       * The number of times to spin before blocking in untimed waits.
# Line 140 | Line 139 | public class LinkedTransferQueue<E> exte
139  
140      /** head of the queue */
141      private transient final PaddedAtomicReference<QNode> head;
142 +
143      /** tail of the queue */
144      private transient final PaddedAtomicReference<QNode> tail;
145  
# Line 166 | Line 166 | public class LinkedTransferQueue<E> exte
166       * Puts or takes an item. Used for most queue operations (except
167       * poll() and tryTransfer()). See the similar code in
168       * SynchronousQueue for detailed explanation.
169 +     *
170       * @param e the item or if null, signifies that this is a take
171       * @param mode the wait mode: NOWAIT, TIMEOUT, WAIT
172       * @param nanos timeout in nanosecs, used only if mode is TIMEOUT
# Line 202 | Line 203 | public class LinkedTransferQueue<E> exte
203                      Object x = first.get();
204                      if (x != first && first.compareAndSet(x, e)) {
205                          LockSupport.unpark(first.waiter);
206 <                        return isData? e : x;
206 >                        return isData ? e : x;
207                      }
208                  }
209              }
# Line 212 | Line 213 | public class LinkedTransferQueue<E> exte
213  
214      /**
215       * Version of xfer for poll() and tryTransfer, which
216 <     * simplifies control paths both here and in xfer
216 >     * simplifies control paths both here and in xfer.
217       */
218      private Object fulfill(Object e) {
219          boolean isData = (e != null);
# Line 240 | Line 241 | public class LinkedTransferQueue<E> exte
241                      Object x = first.get();
242                      if (x != first && first.compareAndSet(x, e)) {
243                          LockSupport.unpark(first.waiter);
244 <                        return isData? e : x;
244 >                        return isData ? e : x;
245                      }
246                  }
247              }
# Line 263 | Line 264 | public class LinkedTransferQueue<E> exte
264          if (mode == NOWAIT)
265              return null;
266  
267 <        long lastTime = (mode == TIMEOUT)? System.nanoTime() : 0;
267 >        long lastTime = (mode == TIMEOUT) ? System.nanoTime() : 0;
268          Thread w = Thread.currentThread();
269          int spins = -1; // set to desired spin count below
270          for (;;) {
# Line 272 | Line 273 | public class LinkedTransferQueue<E> exte
273              Object x = s.get();
274              if (x != e) {                 // Node was matched or cancelled
275                  advanceHead(pred, s);     // unlink if head
276 <                if (x == s) {              // was cancelled
276 >                if (x == s) {             // was cancelled
277                      clean(pred, s);
278                      return null;
279                  }
# Line 295 | Line 296 | public class LinkedTransferQueue<E> exte
296              if (spins < 0) {
297                  QNode h = head.get(); // only spin if at head
298                  spins = ((h != null && h.next == s) ?
299 <                         (mode == TIMEOUT?
299 >                         ((mode == TIMEOUT) ?
300                            maxTimedSpins : maxUntimedSpins) : 0);
301              }
302              if (spins > 0)
# Line 316 | Line 317 | public class LinkedTransferQueue<E> exte
317      }
318  
319      /**
320 <     * Returns validated tail for use in cleaning methods
320 >     * Returns validated tail for use in cleaning methods.
321       */
322      private QNode getValidatedTail() {
323          for (;;) {
# Line 339 | Line 340 | public class LinkedTransferQueue<E> exte
340  
341      /**
342       * Gets rid of cancelled node s with original predecessor pred.
343 +     *
344       * @param pred predecessor of cancelled node
345       * @param s the cancelled node
346       */
# Line 378 | Line 380 | public class LinkedTransferQueue<E> exte
380      /**
381       * Tries to unsplice the cancelled node held in cleanMe that was
382       * previously uncleanable because it was at tail.
383 +     *
384       * @return current cleanMe node (or null)
385       */
386      private QNode reclean() {
# Line 422 | Line 425 | public class LinkedTransferQueue<E> exte
425       * Creates a {@code LinkedTransferQueue}
426       * initially containing the elements of the given collection,
427       * added in traversal order of the collection's iterator.
428 +     *
429       * @param c the collection of elements to initially contain
430       * @throws NullPointerException if the specified collection or any
431       *         of its elements are null
# Line 483 | Line 487 | public class LinkedTransferQueue<E> exte
487      public E take() throws InterruptedException {
488          Object e = xfer(null, WAIT, 0);
489          if (e != null)
490 <            return (E)e;
490 >            return (E) e;
491          Thread.interrupted();
492          throw new InterruptedException();
493      }
# Line 491 | Line 495 | public class LinkedTransferQueue<E> exte
495      public E poll(long timeout, TimeUnit unit) throws InterruptedException {
496          Object e = xfer(null, TIMEOUT, unit.toNanos(timeout));
497          if (e != null || !Thread.interrupted())
498 <            return (E)e;
498 >            return (E) e;
499          throw new InterruptedException();
500      }
501  
502      public E poll() {
503 <        return (E)fulfill(null);
503 >        return (E) fulfill(null);
504      }
505  
506      public int drainTo(Collection<? super E> c) {
# Line 530 | Line 534 | public class LinkedTransferQueue<E> exte
534      // Traversal-based methods
535  
536      /**
537 <     * Return head after performing any outstanding helping steps
537 >     * Returns head after performing any outstanding helping steps.
538       */
539      private QNode traversalHead() {
540          for (;;) {
# Line 575 | Line 579 | public class LinkedTransferQueue<E> exte
579          QNode snext;       // successor of next
580          QNode curr;        // last returned node, for remove()
581          QNode pcurr;       // predecessor of curr, for remove()
582 <        E nextItem;        // Cache of next item, once commited to in next
582 >        E nextItem;        // Cache of next item, once committed to in next
583  
584          Itr() {
585              findNext();
586          }
587  
588          /**
589 <         * Ensure next points to next valid node, or null if none.
589 >         * Ensures next points to next valid node, or null if none.
590           */
591          void findNext() {
592              for (;;) {
# Line 599 | Line 603 | public class LinkedTransferQueue<E> exte
603                  Object x = q.get();
604                  QNode s = q.next;
605                  if (x != null && q != x && q != s) {
606 <                    nextItem = (E)x;
606 >                    nextItem = (E) x;
607                      snext = s;
608                      pnext = pred;
609                      next = q;
# Line 646 | Line 650 | public class LinkedTransferQueue<E> exte
650                  if (!p.isData)
651                      return null;
652                  if (x != null)
653 <                    return (E)x;
653 >                    return (E) x;
654              }
655          }
656      }
# Line 732 | Line 736 | public class LinkedTransferQueue<E> exte
736                  if (q == pred) // restart
737                      break;
738                  Object x = q.get();
739 <                if (x != null && x != q && o.equals(x) &&
739 >                if (x != null && x != q && o.equals(x) &&
740                      q.compareAndSet(x, q)) {
741                      clean(pred, q);
742                      return true;
# Line 752 | Line 756 | public class LinkedTransferQueue<E> exte
756      private void writeObject(java.io.ObjectOutputStream s)
757          throws java.io.IOException {
758          s.defaultWriteObject();
759 <        for (Iterator<E> it = iterator(); it.hasNext(); )
760 <            s.writeObject(it.next());
759 >        for (E e : this)
760 >            s.writeObject(e);
761          // Use trailing null as sentinel
762          s.writeObject(null);
763      }
# Line 761 | Line 765 | public class LinkedTransferQueue<E> exte
765      /**
766       * Reconstitute the Queue instance from a stream (that is,
767       * deserialize it).
768 +     *
769       * @param s the stream
770       */
771      private void readObject(java.io.ObjectInputStream s)
# Line 768 | Line 773 | public class LinkedTransferQueue<E> exte
773          s.defaultReadObject();
774          resetHeadAndTail();
775          for (;;) {
776 <            E item = (E)s.readObject();
776 >            E item = (E) s.readObject();
777              if (item == null)
778                  break;
779              else
# Line 780 | Line 785 | public class LinkedTransferQueue<E> exte
785      // Support for resetting head/tail while deserializing
786      private void resetHeadAndTail() {
787          QNode dummy = new QNode(null, false);
788 <        _unsafe.putObjectVolatile(this, headOffset,
788 >        UNSAFE.putObjectVolatile(this, headOffset,
789                                    new PaddedAtomicReference<QNode>(dummy));
790 <        _unsafe.putObjectVolatile(this, tailOffset,
790 >        UNSAFE.putObjectVolatile(this, tailOffset,
791                                    new PaddedAtomicReference<QNode>(dummy));
792 <        _unsafe.putObjectVolatile(this, cleanMeOffset,
792 >        UNSAFE.putObjectVolatile(this, cleanMeOffset,
793                                    new PaddedAtomicReference<QNode>(null));
794      }
795  
# Line 814 | Line 819 | public class LinkedTransferQueue<E> exte
819  
820      private static long fieldOffset(String fieldName)
821              throws NoSuchFieldException {
822 <        return _unsafe.objectFieldOffset
822 >        return UNSAFE.objectFieldOffset
823              (LinkedTransferQueue.class.getDeclaredField(fieldName));
824      }
825  
826 <    private static final Unsafe _unsafe;
826 >    private static final Unsafe UNSAFE;
827      private static final long headOffset;
828      private static final long tailOffset;
829      private static final long cleanMeOffset;
830      static {
831          try {
832 <            _unsafe = getUnsafe();
832 >            UNSAFE = getUnsafe();
833              headOffset = fieldOffset("head");
834              tailOffset = fieldOffset("tail");
835              cleanMeOffset = fieldOffset("cleanMe");

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines