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.10 by jsr166, Mon Jan 5 03:43:07 2009 UTC vs.
Revision 1.14 by jsr166, Thu Mar 19 05:10:42 2009 UTC

# Line 21 | Line 21 | import java.lang.reflect.*;
21   * producer.  The <em>tail</em> of the queue is that element that has
22   * been on the queue the shortest time for some producer.
23   *
24 < * <p>Beware that, unlike in most collections, the <tt>size</tt>
24 > * <p>Beware that, unlike in most collections, the {@code size}
25   * method is <em>NOT</em> a constant-time operation. Because of the
26   * asynchronous nature of these queues, determining the current number
27   * of elements requires a traversal of the elements.
# Line 298 | Line 298 | public class LinkedTransferQueue<E> exte
298              else if (s.waiter == null)
299                  s.waiter = w;
300              else if (mode != TIMEOUT) {
301 <                //                LockSupport.park(this);
302 <                LockSupport.park(); // allows run on java5
301 >                LockSupport.park(this);
302                  s.waiter = null;
303                  spins = -1;
304              }
305              else if (nanos > spinForTimeoutThreshold) {
306 <                //                LockSupport.parkNanos(this, nanos);
308 <                LockSupport.parkNanos(nanos);
306 >                LockSupport.parkNanos(this, nanos);
307                  s.waiter = null;
308                  spins = -1;
309              }
# Line 402 | Line 400 | public class LinkedTransferQueue<E> exte
400      }
401  
402      /**
403 <     * Creates an initially empty <tt>LinkedTransferQueue</tt>.
403 >     * Creates an initially empty {@code LinkedTransferQueue}.
404       */
405      public LinkedTransferQueue() {
406          QNode dummy = new QNode(null, false);
# Line 412 | Line 410 | public class LinkedTransferQueue<E> exte
410      }
411  
412      /**
413 <     * Creates a <tt>LinkedTransferQueue</tt>
413 >     * Creates a {@code LinkedTransferQueue}
414       * initially containing the elements of the given collection,
415       * added in traversal order of the collection's iterator.
416       * @param c the collection of elements to initially contain
# Line 655 | Line 653 | public class LinkedTransferQueue<E> exte
653  
654      /**
655       * Returns the number of elements in this queue.  If this queue
656 <     * contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
657 <     * <tt>Integer.MAX_VALUE</tt>.
656 >     * contains more than {@code Integer.MAX_VALUE} elements, returns
657 >     * {@code Integer.MAX_VALUE}.
658       *
659       * <p>Beware that, unlike in most collections, this method is
660       * <em>NOT</em> a constant-time operation. Because of the
# Line 697 | Line 695 | public class LinkedTransferQueue<E> exte
695      /**
696       * Save the state to a stream (that is, serialize it).
697       *
698 <     * @serialData All of the elements (each an <tt>E</tt>) in
698 >     * @serialData All of the elements (each an {@code E}) in
699       * the proper order, followed by a null
700       * @param s the stream
701       */
# Line 730 | Line 728 | public class LinkedTransferQueue<E> exte
728  
729  
730      // Support for resetting head/tail while deserializing
731 +    private void resetHeadAndTail() {
732 +        QNode dummy = new QNode(null, false);
733 +        _unsafe.putObjectVolatile(this, headOffset,
734 +                                  new PaddedAtomicReference<QNode>(dummy));
735 +        _unsafe.putObjectVolatile(this, tailOffset,
736 +                                  new PaddedAtomicReference<QNode>(dummy));
737 +        _unsafe.putObjectVolatile(this, cleanMeOffset,
738 +                                  new PaddedAtomicReference<QNode>(null));
739 +    }
740  
741      // Temporary Unsafe mechanics for preliminary release
742 +    private static Unsafe getUnsafe() throws Throwable {
743 +        try {
744 +            return Unsafe.getUnsafe();
745 +        } catch (SecurityException se) {
746 +            try {
747 +                return java.security.AccessController.doPrivileged
748 +                    (new java.security.PrivilegedExceptionAction<Unsafe>() {
749 +                        public Unsafe run() throws Exception {
750 +                            return getUnsafePrivileged();
751 +                        }});
752 +            } catch (java.security.PrivilegedActionException e) {
753 +                throw e.getCause();
754 +            }
755 +        }
756 +    }
757 +
758 +    private static Unsafe getUnsafePrivileged()
759 +            throws NoSuchFieldException, IllegalAccessException {
760 +        Field f = Unsafe.class.getDeclaredField("theUnsafe");
761 +        f.setAccessible(true);
762 +        return (Unsafe) f.get(null);
763 +    }
764 +
765 +    private static long fieldOffset(String fieldName)
766 +            throws NoSuchFieldException {
767 +        return _unsafe.objectFieldOffset
768 +            (LinkedTransferQueue.class.getDeclaredField(fieldName));
769 +    }
770 +
771      private static final Unsafe _unsafe;
772      private static final long headOffset;
773      private static final long tailOffset;
774      private static final long cleanMeOffset;
775      static {
776          try {
777 <            if (LinkedTransferQueue.class.getClassLoader() != null) {
778 <                Field f = Unsafe.class.getDeclaredField("theUnsafe");
779 <                f.setAccessible(true);
780 <                _unsafe = (Unsafe)f.get(null);
781 <            }
746 <            else
747 <                _unsafe = Unsafe.getUnsafe();
748 <            headOffset = _unsafe.objectFieldOffset
749 <                (LinkedTransferQueue.class.getDeclaredField("head"));
750 <            tailOffset = _unsafe.objectFieldOffset
751 <                (LinkedTransferQueue.class.getDeclaredField("tail"));
752 <            cleanMeOffset = _unsafe.objectFieldOffset
753 <                (LinkedTransferQueue.class.getDeclaredField("cleanMe"));
754 <        } catch (Exception e) {
777 >            _unsafe = getUnsafe();
778 >            headOffset = fieldOffset("head");
779 >            tailOffset = fieldOffset("tail");
780 >            cleanMeOffset = fieldOffset("cleanMe");
781 >        } catch (Throwable e) {
782              throw new RuntimeException("Could not initialize intrinsics", e);
783          }
784      }
785  
759    private void resetHeadAndTail() {
760        QNode dummy = new QNode(null, false);
761        _unsafe.putObjectVolatile(this, headOffset,
762                                  new PaddedAtomicReference<QNode>(dummy));
763        _unsafe.putObjectVolatile(this, tailOffset,
764                                  new PaddedAtomicReference<QNode>(dummy));
765        _unsafe.putObjectVolatile(this, cleanMeOffset,
766                                  new PaddedAtomicReference<QNode>(null));
767
768    }
769
786   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines