jdk/src/share/classes/sun/nio/ch/Util.java
changeset 51 6fe31bc95bbc
parent 2 90ce3da70b43
child 715 f16baef3a20e
child 787 637b139ce684
equal deleted inserted replaced
50:a437b3f9d7f4 51:6fe31bc95bbc
    47 
    47 
    48     // The number of temp buffers in our pool
    48     // The number of temp buffers in our pool
    49     private static final int TEMP_BUF_POOL_SIZE = 3;
    49     private static final int TEMP_BUF_POOL_SIZE = 3;
    50 
    50 
    51     // Per-thread soft cache of the last temporary direct buffer
    51     // Per-thread soft cache of the last temporary direct buffer
    52     private static ThreadLocal[] bufferPool;
    52     private static ThreadLocal<SoftReference<ByteBuffer>>[] bufferPool;
    53 
    53 
    54     static {
    54     static {
    55         bufferPool = new ThreadLocal[TEMP_BUF_POOL_SIZE];
    55         bufferPool = (ThreadLocal<SoftReference<ByteBuffer>>[])
       
    56             new ThreadLocal[TEMP_BUF_POOL_SIZE];
    56         for (int i=0; i<TEMP_BUF_POOL_SIZE; i++)
    57         for (int i=0; i<TEMP_BUF_POOL_SIZE; i++)
    57             bufferPool[i] = new ThreadLocal();
    58             bufferPool[i] = new ThreadLocal<SoftReference<ByteBuffer>>();
    58     }
    59     }
    59 
    60 
    60     static ByteBuffer getTemporaryDirectBuffer(int size) {
    61     static ByteBuffer getTemporaryDirectBuffer(int size) {
    61         ByteBuffer buf = null;
    62         ByteBuffer buf = null;
    62         // Grab a buffer if available
    63         // Grab a buffer if available
    63         for (int i=0; i<TEMP_BUF_POOL_SIZE; i++) {
    64         for (int i=0; i<TEMP_BUF_POOL_SIZE; i++) {
    64             SoftReference ref = (SoftReference)(bufferPool[i].get());
    65             SoftReference<ByteBuffer> ref = bufferPool[i].get();
    65             if ((ref != null) && ((buf = (ByteBuffer)ref.get()) != null) &&
    66             if ((ref != null) && ((buf = ref.get()) != null) &&
    66                 (buf.capacity() >= size)) {
    67                 (buf.capacity() >= size)) {
    67                 buf.rewind();
    68                 buf.rewind();
    68                 buf.limit(size);
    69                 buf.limit(size);
    69                 bufferPool[i].set(null);
    70                 bufferPool[i].set(null);
    70                 return buf;
    71                 return buf;
    78     static void releaseTemporaryDirectBuffer(ByteBuffer buf) {
    79     static void releaseTemporaryDirectBuffer(ByteBuffer buf) {
    79         if (buf == null)
    80         if (buf == null)
    80             return;
    81             return;
    81         // Put it in an empty slot if such exists
    82         // Put it in an empty slot if such exists
    82         for (int i=0; i<TEMP_BUF_POOL_SIZE; i++) {
    83         for (int i=0; i<TEMP_BUF_POOL_SIZE; i++) {
    83             SoftReference ref = (SoftReference)(bufferPool[i].get());
    84             SoftReference<ByteBuffer> ref = bufferPool[i].get();
    84             if ((ref == null) || (ref.get() == null)) {
    85             if ((ref == null) || (ref.get() == null)) {
    85                 bufferPool[i].set(new SoftReference(buf));
    86                 bufferPool[i].set(new SoftReference<ByteBuffer>(buf));
    86                 return;
    87                 return;
    87             }
    88             }
    88         }
    89         }
    89         // Otherwise replace a smaller one in the cache if such exists
    90         // Otherwise replace a smaller one in the cache if such exists
    90         for (int i=0; i<TEMP_BUF_POOL_SIZE; i++) {
    91         for (int i=0; i<TEMP_BUF_POOL_SIZE; i++) {
    91             SoftReference ref = (SoftReference)(bufferPool[i].get());
    92             SoftReference<ByteBuffer> ref = bufferPool[i].get();
    92             ByteBuffer inCacheBuf = (ByteBuffer)ref.get();
    93             ByteBuffer inCacheBuf = ref.get();
    93             if ((inCacheBuf == null) || (buf.capacity() > inCacheBuf.capacity())) {
    94             if ((inCacheBuf == null) || (buf.capacity() > inCacheBuf.capacity())) {
    94                 bufferPool[i].set(new SoftReference(buf));
    95                 bufferPool[i].set(new SoftReference<ByteBuffer>(buf));
    95                 return;
    96                 return;
    96             }
    97             }
    97         }
    98         }
    98     }
    99     }
    99 
   100 
   118         }
   119         }
   119         public Selector get() { return sel;}
   120         public Selector get() { return sel;}
   120     }
   121     }
   121 
   122 
   122     // Per-thread cached selector
   123     // Per-thread cached selector
   123     private static ThreadLocal localSelector = new ThreadLocal();
   124     private static ThreadLocal<SoftReference<SelectorWrapper>> localSelector
       
   125         = new ThreadLocal<SoftReference<SelectorWrapper>>();
   124     // Hold a reference to the selWrapper object to prevent it from
   126     // Hold a reference to the selWrapper object to prevent it from
   125     // being cleaned when the temporary selector wrapped is on lease.
   127     // being cleaned when the temporary selector wrapped is on lease.
   126     private static ThreadLocal localSelectorWrapper = new ThreadLocal();
   128     private static ThreadLocal<SelectorWrapper> localSelectorWrapper
       
   129         = new ThreadLocal<SelectorWrapper>();
   127 
   130 
   128     // When finished, invoker must ensure that selector is empty
   131     // When finished, invoker must ensure that selector is empty
   129     // by cancelling any related keys and explicitly releasing
   132     // by cancelling any related keys and explicitly releasing
   130     // the selector by invoking releaseTemporarySelector()
   133     // the selector by invoking releaseTemporarySelector()
   131     static Selector getTemporarySelector(SelectableChannel sc)
   134     static Selector getTemporarySelector(SelectableChannel sc)
   132         throws IOException
   135         throws IOException
   133     {
   136     {
   134         SoftReference ref = (SoftReference)localSelector.get();
   137         SoftReference<SelectorWrapper> ref = localSelector.get();
   135         SelectorWrapper selWrapper = null;
   138         SelectorWrapper selWrapper = null;
   136         Selector sel = null;
   139         Selector sel = null;
   137         if (ref == null
   140         if (ref == null
   138             || ((selWrapper = (SelectorWrapper) ref.get()) == null)
   141             || ((selWrapper = ref.get()) == null)
   139             || ((sel = selWrapper.get()) == null)
   142             || ((sel = selWrapper.get()) == null)
   140             || (sel.provider() != sc.provider())) {
   143             || (sel.provider() != sc.provider())) {
   141             sel = sc.provider().openSelector();
   144             sel = sc.provider().openSelector();
   142             localSelector.set(new SoftReference(new SelectorWrapper(sel)));
   145             localSelector.set(new SoftReference<SelectorWrapper>(
       
   146                                   new SelectorWrapper(sel)));
   143         } else {
   147         } else {
   144             localSelectorWrapper.set(selWrapper);
   148             localSelectorWrapper.set(selWrapper);
   145         }
   149         }
   146         return sel;
   150         return sel;
   147     }
   151     }
   233     }
   237     }
   234 
   238 
   235     private static volatile Constructor directByteBufferConstructor = null;
   239     private static volatile Constructor directByteBufferConstructor = null;
   236 
   240 
   237     private static void initDBBConstructor() {
   241     private static void initDBBConstructor() {
   238         AccessController.doPrivileged(new PrivilegedAction() {
   242         AccessController.doPrivileged(new PrivilegedAction<Void>() {
   239                 public Object run() {
   243                 public Void run() {
   240                     try {
   244                     try {
   241                         Class cl = Class.forName("java.nio.DirectByteBuffer");
   245                         Class<?> cl = Class.forName("java.nio.DirectByteBuffer");
   242                         Constructor ctor = cl.getDeclaredConstructor(
   246                         Constructor ctor = cl.getDeclaredConstructor(
   243                             new Class[] { int.class,
   247                             new Class[] { int.class,
   244                                           long.class,
   248                                           long.class,
   245                                           Runnable.class });
   249                                           Runnable.class });
   246                         ctor.setAccessible(true);
   250                         ctor.setAccessible(true);
   280     }
   284     }
   281 
   285 
   282     private static volatile Constructor directByteBufferRConstructor = null;
   286     private static volatile Constructor directByteBufferRConstructor = null;
   283 
   287 
   284     private static void initDBBRConstructor() {
   288     private static void initDBBRConstructor() {
   285         AccessController.doPrivileged(new PrivilegedAction() {
   289         AccessController.doPrivileged(new PrivilegedAction<Void>() {
   286                 public Object run() {
   290                 public Void run() {
   287                     try {
   291                     try {
   288                         Class cl = Class.forName("java.nio.DirectByteBufferR");
   292                         Class<?> cl = Class.forName("java.nio.DirectByteBufferR");
   289                         Constructor ctor = cl.getDeclaredConstructor(
   293                         Constructor ctor = cl.getDeclaredConstructor(
   290                             new Class[] { int.class,
   294                             new Class[] { int.class,
   291                                           long.class,
   295                                           long.class,
   292                                           Runnable.class });
   296                                           Runnable.class });
   293                         ctor.setAccessible(true);
   297                         ctor.setAccessible(true);