EMMA Coverage Report (generated Mon Jul 11 13:15:38 KST 2005)
[all classes][org.apache.mina.io.filter]

COVERAGE SUMMARY FOR SOURCE FILE [SSLByteBufferPool.java]

nameclass, %method, %block, %line, %
SSLByteBufferPool.java100% (1/1)82%  (9/11)71%  (126/177)72%  (39.1/54)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class SSLByteBufferPool100% (1/1)82%  (9/11)71%  (126/177)72%  (39.1/54)
SSLByteBufferPool (): void 0%   (0/1)0%   (0/3)0%   (0/1)
expandBuffer (ByteBuffer, int): ByteBuffer 0%   (0/1)0%   (0/14)0%   (0/5)
createBuffer (int): ByteBuffer 100% (1/1)36%  (5/14)33%  (2/6)
getApplicationBuffer (): ByteBuffer 100% (1/1)50%  (5/10)67%  (2/3)
getPacketBuffer (): ByteBuffer 100% (1/1)50%  (5/10)67%  (2/3)
release (ByteBuffer): void 100% (1/1)82%  (23/28)97%  (6.8/7)
getBufferStackIndex (int): int 100% (1/1)83%  (10/12)80%  (4/5)
allocate (int): ByteBuffer 100% (1/1)84%  (27/32)92%  (7.4/8)
initiate (SSLEngine): void 100% (1/1)86%  (19/22)89%  (8/9)
<static initializer> 100% (1/1)100% (20/20)100% (3/3)
initiateBufferStacks (): void 100% (1/1)100% (12/12)100% (4/4)

1/*
2 *   @(#) $Id: SSLByteBufferPool.java 210062 2005-07-11 03:52:38Z trustin $
3 *
4 *   Copyright 2004 The Apache Software Foundation
5 *
6 *   Licensed under the Apache License, Version 2.0 (the "License");
7 *   you may not use this file except in compliance with the License.
8 *   You may obtain a copy of the License at
9 *
10 *       http://www.apache.org/licenses/LICENSE-2.0
11 *
12 *   Unless required by applicable law or agreed to in writing, software
13 *   distributed under the License is distributed on an "AS IS" BASIS,
14 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 *   See the License for the specific language governing permissions and
16 *   limitations under the License.
17 *
18 */
19package org.apache.mina.io.filter;
20 
21import java.nio.ByteBuffer;
22 
23import javax.net.ssl.SSLEngine;
24 
25import org.apache.mina.util.Stack;
26 
27/**
28 * Simple ByteBuffer pool used by SSLHandler.
29 * ByteBuffers are by default allocated as direct byte buffers. To use non-direct
30 * ByteBuffers, set system property mina.sslfilter.directbuffer to false.
31 *
32 * @author Jan Andersson (janne@minq.se)
33 * @version $Rev: 210062 $, $Date: 2005-07-11 12:52:38 +0900 $
34 */
35class SSLByteBufferPool
36{
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    /**
57     * Initiate buffer pool and buffer sizes from SSLEngine session.
58     *
59     * @param sslEngine SSLEngine
60     */
61    static synchronized void initiate( SSLEngine sslEngine )
62    {
63        if( !initiated )
64        {
65            // Use direct allocated memory or not?
66            String prop = System.getProperty( DIRECT_MEMORY_PROP );
67            if( prop != null )
68            {
69                useDirectAllocatedBuffers = Boolean
70                        .getBoolean( DIRECT_MEMORY_PROP );
71            }
72            
73            // init buffer sizes from SSLEngine
74            packetBufferSize = sslEngine.getSession().getPacketBufferSize();
75 
76            // application buffer size has been doubled because SSLEngine
77            // returns BUFFER_OVERFLOW even if there is enough room for the buffer.
78            // So for now we use a size double the packet size as a workaround.
79            appBufferSize = packetBufferSize * 2;
80            initiateBufferStacks();
81            initiated = true;
82        }
83    }
84 
85    /**
86     * Get bytebuffer with size the size of the largest SSL/TLS packet that may occur
87     * (as defined by SSLSession).
88     */
89    static ByteBuffer getPacketBuffer()
90    {
91        if( !initiated )
92        {
93            throw new IllegalStateException( "Not initialized" );
94        }
95        return allocate( PACKET_BUFFER_INDEX );
96    }
97 
98    /**
99     * Get ByteBuffer with the size of the largest application buffer that may occur
100     * (as defined by SSLSession).
101     */
102    static ByteBuffer getApplicationBuffer()
103    {
104        if( !initiated )
105        {
106            throw new IllegalStateException( "Not initialized" );
107        }
108        return allocate( APPLICATION_BUFFER_INDEX );
109    }
110 
111    /**
112     * Allocate or get the buffer which is capable of the specified size.
113     */
114    private static ByteBuffer allocate( int idx )
115    {
116        Stack stack = bufferStacks[ idx ];
117 
118        ByteBuffer buf;
119        synchronized( stack )
120        {
121            buf = ( ByteBuffer ) stack.pop();
122            if( buf == null )
123            {
124                buf = createBuffer( bufferStackSizes[ idx ] );
125            }
126        }
127 
128        buf.clear();
129        return buf;
130    }
131 
132    /**
133     * Releases the specified buffer to buffer pool.
134     */
135    public static void release( ByteBuffer buf )
136    {
137        int stackIndex =getBufferStackIndex( buf.capacity() );
138        if ( stackIndex >= PACKET_BUFFER_INDEX ) {
139            Stack stack = bufferStacks[getBufferStackIndex( buf.capacity() )];
140            synchronized ( stack ) {
141                stack.push( buf );
142            }
143        }
144    }
145 
146    /**
147     * Expand size of provided buffer
148     * @param buf buffer to be expande
149     * @param newCapacity new capacity
150     */
151    public static ByteBuffer expandBuffer( ByteBuffer buf, int newCapacity )
152    {
153        ByteBuffer newBuf = createBuffer( newCapacity );
154        buf.flip();
155        newBuf.put( buf );
156        release(buf);
157        return newBuf;
158    }
159 
160    private static void initiateBufferStacks()
161    {
162        bufferStackSizes = new int[ 2 ];
163        bufferStackSizes[ PACKET_BUFFER_INDEX ] = packetBufferSize;
164        bufferStackSizes[ APPLICATION_BUFFER_INDEX ] = appBufferSize;
165    }
166 
167    private static int getBufferStackIndex( int size )
168    {
169        if( size == packetBufferSize )
170            return PACKET_BUFFER_INDEX;
171        if( size == appBufferSize )
172            return APPLICATION_BUFFER_INDEX;
173        return -1;  // not reused
174    }
175 
176    private static ByteBuffer createBuffer( int capacity )
177    {
178        if( useDirectAllocatedBuffers )
179        {
180            try
181            {
182                return ByteBuffer.allocateDirect( capacity );
183            }
184            catch( OutOfMemoryError e )
185            {
186                useDirectAllocatedBuffers = false;
187                System.err
188                        .println( "OutOfMemoryError: No more direct buffers available; trying heap buffer instead" );
189            }
190        }
191        return ByteBuffer.allocate( capacity );
192    }
193 
194}

[all classes][org.apache.mina.io.filter]
EMMA 2.0.4217 (C) Vladimir Roubtsov