1 /* 2 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.nio.ch; 27 28 import java.nio.ByteBuffer; 29 import sun.misc.*; 30 31 32 /** 33 * Manipulates a native array of iovec structs on Solaris: 34 * 35 * typedef struct iovec { 36 * caddr_t iov_base; 37 int iov_len; 38 * } iovec_t; 39 * 40 * @author Mike McCloskey 41 * @since 1.4 42 */ 43 44 class IOVecWrapper { 45 46 // Miscellaneous constants 47 private static final int BASE_OFFSET = 0; 48 private static final int LEN_OFFSET; 49 private static final int SIZE_IOVEC; 50 51 // The iovec array 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; 64 65 // Base address of this array 66 final long address; 67 68 // Address size in bytes 69 static int addressSize; 70 71 private static class Deallocator implements Runnable { 72 private final AllocatedNativeObject obj; Deallocator(AllocatedNativeObject obj)73 Deallocator(AllocatedNativeObject obj) { 74 this.obj = obj; 75 } run()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 IOVecWrapper(int size)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 get(int size)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 setBuffer(int i, ByteBuffer buf, int pos, int rem)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 setShadow(int i, ByteBuffer buf)116 void setShadow(int i, ByteBuffer buf) { 117 shadow[i] = buf; 118 } 119 getBuffer(int i)120 ByteBuffer getBuffer(int i) { 121 return buf[i]; 122 } 123 getPosition(int i)124 int getPosition(int i) { 125 return position[i]; 126 } 127 getRemaining(int i)128 int getRemaining(int i) { 129 return remaining[i]; 130 } 131 getShadow(int i)132 ByteBuffer getShadow(int i) { 133 return shadow[i]; 134 } 135 clearRefs(int i)136 void clearRefs(int i) { 137 buf[i] = null; 138 shadow[i] = null; 139 } 140 putBase(int i, long base)141 void putBase(int i, long base) { 142 int offset = SIZE_IOVEC * i + BASE_OFFSET; 143 if (addressSize == 4) 144 vecArray.putInt(offset, (int)base); 145 else 146 vecArray.putLong(offset, base); 147 } 148 putLen(int i, long len)149 void putLen(int i, long len) { 150 int offset = SIZE_IOVEC * i + LEN_OFFSET; 151 if (addressSize == 4) 152 vecArray.putInt(offset, (int)len); 153 else 154 vecArray.putLong(offset, len); 155 } 156 157 static { 158 addressSize = Util.unsafe().addressSize(); 159 LEN_OFFSET = addressSize; 160 SIZE_IOVEC = (short) (addressSize * 2); 161 } 162 } 163