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.6 by jsr166, Fri Jul 25 18:13:15 2008 UTC vs.
Revision 1.7 by dl, Wed Sep 24 10:48:43 2008 UTC

# Line 10 | Line 10 | import java.util.concurrent.locks.*;
10   import java.util.concurrent.atomic.*;
11   import java.util.*;
12   import java.io.*;
13 + import sun.misc.Unsafe;
14 + import java.lang.reflect.*;
15  
16   /**
17   * An unbounded {@linkplain TransferQueue} based on linked nodes.
# Line 131 | Line 133 | public class LinkedTransferQueue<E> exte
133      }
134  
135  
136 <    private final QNode dummy = new QNode(null, false);
137 <    private final PaddedAtomicReference<QNode> head =
138 <        new PaddedAtomicReference<QNode>(dummy);
139 <    private final PaddedAtomicReference<QNode> tail =
138 <        new PaddedAtomicReference<QNode>(dummy);
136 >    /** head of the queue */
137 >    private transient final PaddedAtomicReference<QNode> head;
138 >    /** tail of the queue */
139 >    private transient final PaddedAtomicReference<QNode> tail;
140  
141      /**
142       * Reference to a cancelled node that might not yet have been
143       * unlinked from queue because it was the last inserted node
144       * when it cancelled.
145       */
146 <    private final PaddedAtomicReference<QNode> cleanMe =
146 <        new PaddedAtomicReference<QNode>(null);
146 >    private transient final PaddedAtomicReference<QNode> cleanMe;
147  
148      /**
149       * Tries to cas nh as new head; if successful, unlink
# Line 370 | Line 370 | public class LinkedTransferQueue<E> exte
370       * Creates an initially empty <tt>LinkedTransferQueue</tt>.
371       */
372      public LinkedTransferQueue() {
373 +        QNode dummy = new QNode(null, false);
374 +        head = new PaddedAtomicReference<QNode>(dummy);
375 +        tail = new PaddedAtomicReference<QNode>(dummy);
376 +        cleanMe = new PaddedAtomicReference<QNode>(null);
377      }
378  
379      /**
# Line 381 | Line 385 | public class LinkedTransferQueue<E> exte
385       *         of its elements are null
386       */
387      public LinkedTransferQueue(Collection<? extends E> c) {
388 +        this();
389          addAll(c);
390      }
391  
# Line 678 | Line 683 | public class LinkedTransferQueue<E> exte
683      private void readObject(java.io.ObjectInputStream s)
684          throws java.io.IOException, ClassNotFoundException {
685          s.defaultReadObject();
686 +        resetHeadAndTail();
687          for (;;) {
688              E item = (E)s.readObject();
689              if (item == null)
# Line 686 | Line 692 | public class LinkedTransferQueue<E> exte
692                  offer(item);
693          }
694      }
695 +
696 +
697 +    // Support for resetting head/tail while deserializing
698 +
699 +    // Temporary Unsafe mechanics for preliminary release
700 +    private static final Unsafe _unsafe;
701 +    private static final long headOffset;
702 +    private static final long tailOffset;
703 +    private static final long cleanMeOffset;
704 +    static {
705 +        try {
706 +            if (LinkedTransferQueue.class.getClassLoader() != null) {
707 +                Field f = Unsafe.class.getDeclaredField("theUnsafe");
708 +                f.setAccessible(true);
709 +                _unsafe = (Unsafe)f.get(null);
710 +            }
711 +            else
712 +                _unsafe = Unsafe.getUnsafe();
713 +            headOffset = _unsafe.objectFieldOffset
714 +                (LinkedTransferQueue.class.getDeclaredField("head"));
715 +            tailOffset = _unsafe.objectFieldOffset
716 +                (LinkedTransferQueue.class.getDeclaredField("tail"));
717 +            cleanMeOffset = _unsafe.objectFieldOffset
718 +                (LinkedTransferQueue.class.getDeclaredField("cleanMe"));
719 +        } catch (Exception e) {
720 +            throw new RuntimeException("Could not initialize intrinsics", e);
721 +        }
722 +    }
723 +
724 +    private void resetHeadAndTail() {
725 +        QNode dummy = new QNode(null, false);
726 +        _unsafe.putObjectVolatile(this, headOffset, dummy);
727 +        _unsafe.putObjectVolatile(this, tailOffset, dummy);
728 +        _unsafe.putObjectVolatile(this, cleanMeOffset,
729 +                                  new PaddedAtomicReference<QNode>(null));
730 +
731 +    }
732 +
733   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines