jdk/src/share/classes/sun/nio/ch/IOVecWrapper.java
changeset 6301 c90a67d75c9f
parent 5506 202f599c92aa
child 7668 d4a77089c587
equal deleted inserted replaced
6300:700ec2a5d680 6301:c90a67d75c9f
    23  * questions.
    23  * questions.
    24  */
    24  */
    25 
    25 
    26 package sun.nio.ch;
    26 package sun.nio.ch;
    27 
    27 
       
    28 import java.nio.ByteBuffer;
    28 import sun.misc.*;
    29 import sun.misc.*;
    29 
    30 
    30 
    31 
    31 /**
    32 /**
    32  * Manipulates a native array of iovec structs on Solaris:
    33  * Manipulates a native array of iovec structs on Solaris:
    41  */
    42  */
    42 
    43 
    43 class IOVecWrapper {
    44 class IOVecWrapper {
    44 
    45 
    45     // Miscellaneous constants
    46     // Miscellaneous constants
    46     static int BASE_OFFSET = 0;
    47     private static final int BASE_OFFSET = 0;
    47     static int LEN_OFFSET;
    48     private static final int LEN_OFFSET;
    48     static int SIZE_IOVEC;
    49     private static final int SIZE_IOVEC;
    49 
    50 
    50     // The iovec array
    51     // The iovec array
    51     private AllocatedNativeObject vecArray;
    52     private final AllocatedNativeObject vecArray;
       
    53 
       
    54     // Number of elements in iovec array
       
    55     private final int size;
       
    56 
       
    57     // Buffers and position/remaining corresponding to elements in iovec array
       
    58     private final ByteBuffer[] buf;
       
    59     private final int[] position;
       
    60     private final int[] remaining;
       
    61 
       
    62     // Shadow buffers for cases when original buffer is substituted
       
    63     private final ByteBuffer[] shadow;
    52 
    64 
    53     // Base address of this array
    65     // Base address of this array
    54     long address;
    66     final long address;
    55 
    67 
    56     // Address size in bytes
    68     // Address size in bytes
    57     static int addressSize;
    69     static int addressSize;
    58 
    70 
    59     IOVecWrapper(int newSize) {
    71     private static class Deallocator implements Runnable {
    60         newSize = (newSize + 1) * SIZE_IOVEC;
    72         private final AllocatedNativeObject obj;
    61         vecArray = new AllocatedNativeObject(newSize, false);
    73         Deallocator(AllocatedNativeObject obj) {
    62         address = vecArray.address();
    74             this.obj = obj;
       
    75         }
       
    76         public void run() {
       
    77             obj.free();
       
    78         }
       
    79     }
       
    80 
       
    81     // per thread IOVecWrapper
       
    82     private static final ThreadLocal<IOVecWrapper> cached =
       
    83         new ThreadLocal<IOVecWrapper>();
       
    84 
       
    85     private IOVecWrapper(int size) {
       
    86         this.size      = size;
       
    87         this.buf       = new ByteBuffer[size];
       
    88         this.position  = new int[size];
       
    89         this.remaining = new int[size];
       
    90         this.shadow    = new ByteBuffer[size];
       
    91         this.vecArray  = new AllocatedNativeObject(size * SIZE_IOVEC, false);
       
    92         this.address   = vecArray.address();
       
    93     }
       
    94 
       
    95     static IOVecWrapper get(int size) {
       
    96         IOVecWrapper wrapper = cached.get();
       
    97         if (wrapper != null && wrapper.size < size) {
       
    98             // not big enough; eagerly release memory
       
    99             wrapper.vecArray.free();
       
   100             wrapper = null;
       
   101         }
       
   102         if (wrapper == null) {
       
   103             wrapper = new IOVecWrapper(size);
       
   104             Cleaner.create(wrapper, new Deallocator(wrapper.vecArray));
       
   105             cached.set(wrapper);
       
   106         }
       
   107         return wrapper;
       
   108     }
       
   109 
       
   110     void setBuffer(int i, ByteBuffer buf, int pos, int rem) {
       
   111         this.buf[i] = buf;
       
   112         this.position[i] = pos;
       
   113         this.remaining[i] = rem;
       
   114     }
       
   115 
       
   116     void setShadow(int i, ByteBuffer buf) {
       
   117         shadow[i] = buf;
       
   118     }
       
   119 
       
   120     ByteBuffer getBuffer(int i) {
       
   121         return buf[i];
       
   122     }
       
   123 
       
   124     int getPosition(int i) {
       
   125         return position[i];
       
   126     }
       
   127 
       
   128     int getRemaining(int i) {
       
   129         return remaining[i];
       
   130     }
       
   131 
       
   132     ByteBuffer getShadow(int i) {
       
   133         return shadow[i];
       
   134     }
       
   135 
       
   136     void clearRefs(int i) {
       
   137         buf[i] = null;
       
   138         shadow[i] = null;
    63     }
   139     }
    64 
   140 
    65     void putBase(int i, long base) {
   141     void putBase(int i, long base) {
    66         int offset = SIZE_IOVEC * i + BASE_OFFSET;
   142         int offset = SIZE_IOVEC * i + BASE_OFFSET;
    67         if (addressSize == 4)
   143         if (addressSize == 4)
    76             vecArray.putInt(offset, (int)len);
   152             vecArray.putInt(offset, (int)len);
    77         else
   153         else
    78             vecArray.putLong(offset, len);
   154             vecArray.putLong(offset, len);
    79     }
   155     }
    80 
   156 
    81     void free() {
       
    82         vecArray.free();
       
    83     }
       
    84 
       
    85     static {
   157     static {
    86         addressSize = Util.unsafe().addressSize();
   158         addressSize = Util.unsafe().addressSize();
    87         LEN_OFFSET = addressSize;
   159         LEN_OFFSET = addressSize;
    88         SIZE_IOVEC = (short) (addressSize * 2);
   160         SIZE_IOVEC = (short) (addressSize * 2);
    89     }
   161     }