1 20 package org.apache.mina.filter.support; 21 22 import java.nio.ByteBuffer ; 23 24 import javax.net.ssl.SSLEngine; 25 26 import org.apache.mina.util.Stack; 27 28 36 class SSLByteBufferPool { 37 private static final int PACKET_BUFFER_INDEX = 0; 38 39 private static final int APPLICATION_BUFFER_INDEX = 1; 40 41 private static boolean initiated = false; 42 43 private static final String DIRECT_MEMORY_PROP = "mina.sslfilter.directbuffer"; 44 45 private static boolean useDirectAllocatedBuffers = true; 46 47 private static int packetBufferSize; 48 49 private static int appBufferSize; 50 51 private static int[] bufferStackSizes; 52 53 private static final Stack[] bufferStacks = new Stack[] { new Stack(), 54 new Stack(), }; 55 56 61 static synchronized void initiate(SSLEngine sslEngine) { 62 if (!initiated) { 63 String prop = System.getProperty(DIRECT_MEMORY_PROP); 65 if (prop != null) { 66 useDirectAllocatedBuffers = Boolean 67 .getBoolean(DIRECT_MEMORY_PROP); 68 } 69 70 packetBufferSize = sslEngine.getSession().getPacketBufferSize(); 72 73 appBufferSize = packetBufferSize * 2; 77 initiateBufferStacks(); 78 initiated = true; 79 } 80 } 81 82 86 static ByteBuffer getPacketBuffer() { 87 if (!initiated) { 88 throw new IllegalStateException ("Not initialized"); 89 } 90 return allocate(PACKET_BUFFER_INDEX); 91 } 92 93 97 static ByteBuffer getApplicationBuffer() { 98 if (!initiated) { 99 throw new IllegalStateException ("Not initialized"); 100 } 101 return allocate(APPLICATION_BUFFER_INDEX); 102 } 103 104 107 private static ByteBuffer allocate(int idx) { 108 Stack stack = bufferStacks[idx]; 109 110 ByteBuffer buf; 111 synchronized (stack) { 112 buf = (ByteBuffer ) stack.pop(); 113 if (buf == null) { 114 buf = createBuffer(bufferStackSizes[idx]); 115 } 116 } 117 118 buf.clear(); 119 return buf; 120 } 121 122 125 public static void release(ByteBuffer buf) { 126 org.apache.mina.common.ByteBuffer.wrap(buf).sweep().release(); 128 129 int stackIndex = getBufferStackIndex(buf.capacity()); 130 if (stackIndex >= PACKET_BUFFER_INDEX) { 131 Stack stack = bufferStacks[getBufferStackIndex(buf.capacity())]; 132 synchronized (stack) { 133 stack.push(buf); 134 } 135 } 136 } 137 138 143 public static ByteBuffer expandBuffer(ByteBuffer buf, int newCapacity) { 144 ByteBuffer newBuf = createBuffer(newCapacity); 145 buf.flip(); 146 newBuf.put(buf); 147 release(buf); 148 return newBuf; 149 } 150 151 private static void initiateBufferStacks() { 152 bufferStackSizes = new int[2]; 153 bufferStackSizes[PACKET_BUFFER_INDEX] = packetBufferSize; 154 bufferStackSizes[APPLICATION_BUFFER_INDEX] = appBufferSize; 155 } 156 157 private static int getBufferStackIndex(int size) { 158 if (size == packetBufferSize) 159 return PACKET_BUFFER_INDEX; 160 if (size == appBufferSize) 161 return APPLICATION_BUFFER_INDEX; 162 return -1; } 164 165 private static ByteBuffer createBuffer(int capacity) { 166 if (useDirectAllocatedBuffers) { 167 try { 168 return ByteBuffer.allocateDirect(capacity); 169 } catch (OutOfMemoryError e) { 170 useDirectAllocatedBuffers = false; 171 System.err 172 .println("OutOfMemoryError: No more direct buffers available; trying heap buffer instead"); 173 } 174 } 175 return ByteBuffer.allocate(capacity); 176 } 177 178 } 179 | Popular Tags |