KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > corba > se > impl > transport > ByteBufferPoolImpl


1 /*
2  * @(#)ByteBufferPoolImpl.java 1.12 04/06/21
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package com.sun.corba.se.impl.transport;
9
10 import java.nio.ByteBuffer JavaDoc;
11 import java.util.ArrayList JavaDoc;
12
13 import com.sun.corba.se.spi.orb.ORB;
14
15 import com.sun.corba.se.pept.transport.ByteBufferPool;
16
17 /**
18  * @author Charlie Hunt
19  */

20
21 public class ByteBufferPoolImpl implements ByteBufferPool
22 {
23     private ORB itsOrb;
24     private int itsByteBufferSize;
25     private ArrayList JavaDoc itsPool;
26     private int itsObjectCounter = 0;
27     private boolean debug;
28
29     // Construct a ByteBufferPool for a pool of NIO ByteBuffers
30
// of ORB fragment size.
31
public ByteBufferPoolImpl(ORB theORB)
32     {
33         itsByteBufferSize = theORB.getORBData().getGIOPFragmentSize();
34         itsPool = new ArrayList JavaDoc();
35         itsOrb = theORB;
36         debug = theORB.transportDebugFlag;
37     }
38
39     /*
40      * Locations where ByteBuffers are gotten from the pool:
41      * 1. ContactInfoBase.createMessageMediator()
42      * 2. ByteBufferWithInfo.growBuffer()
43      * 3. ByteBufferWithInfo(ORB, BufferManagerWrite) - constructor
44     */

45
46     // If the requested ByteBuffer size is less than or equal to
47
// the ORB fragment size, and we have not disabled use of
48
// direct byte buffers (normally for debugging purposes)
49
// then get a DirectByteBuffer from the
50
// pool if there is one, if there is not one in the pool,
51
// then allocate a a DirectByteBuffer of ORB fragment size.
52
//
53
// If the request ByteBuffer size is greater than the ORB fragment
54
// size, allocate a new non-direct ByteBuffer.
55
public ByteBuffer JavaDoc getByteBuffer(int theAskSize)
56     {
57         ByteBuffer JavaDoc abb = null;
58
59         if ((theAskSize <= itsByteBufferSize) &&
60         !itsOrb.getORBData().disableDirectByteBufferUse())
61         {
62             // check if there's one in the pool, if not allocate one.
63
int poolSize;
64             synchronized (itsPool)
65             {
66                 poolSize = itsPool.size();
67                 if (poolSize > 0)
68                 {
69                     abb = (ByteBuffer JavaDoc)itsPool.remove(poolSize - 1);
70
71                     // clear ByteBuffer before returning it
72
abb.clear();
73                 }
74             }
75
76             // NOTE: Moved the 'else' part of the above if statement
77
// outside the synchronized block since it is likely
78
// less expensive to check poolSize than to allocate a
79
// DirectByteBuffer in the synchronized block.
80
if (poolSize <= 0)
81             {
82                 abb = ByteBuffer.allocateDirect(itsByteBufferSize);
83             }
84
85             // increment the number of ByteBuffers gotten from pool
86
// IMPORTANT: Since this counter is used only for information
87
// purposes, it does not use synchronized access.
88
itsObjectCounter++;
89         }
90         else
91         {
92             // Requested ByteBuffer size larger than the pool manages.
93
// Just allocate a non-direct ByteBuffer
94
abb = ByteBuffer.allocate(theAskSize);
95         }
96
97     return abb;
98     }
99
100
101     /*
102      * Locations where ByteBuffers are released to the pool:
103      * 1. ByteBufferWithInfo.growBuffer()
104      * 2. BufferManagerWriteCollect.sendMessage()
105      * 3. CDROutputStream_1_0.close()
106      * 4. CDRInputStream_1_0.close()
107      * 5. BufferManagerReadStream.underflow()
108      * 6. BufferManagerWrite.close()
109      * 7. BufferManagerRead.close()
110      * 8. CorbaMessageMediatorImpl.releaseByteBufferToPool()
111     */

112
113     // If the ByteBuffer is a DirectByteBuffer, add it to the pool.
114
// Otherwise, set its reference to null since it's not kept in
115
// the pool and caller is saying he/she is done with it.
116
// NOTE: The size of the ByteBuffer is not checked with the
117
// this pool's ByteBuffer size since only DirectByteBuffers
118
// ever allocated. Hence, only DirectByteBuffer are checked
119
// here. An additional check could be added here for that though.
120
public void releaseByteBuffer(ByteBuffer JavaDoc thebb)
121     {
122         if (thebb.isDirect())
123         {
124             synchronized (itsPool)
125             {
126                 // use with debug to determine if byteBuffer is already
127
// in the pool.
128
boolean refInPool = false;
129                 int bbAddr = 0;
130
131                 if (debug)
132                 {
133                     // Check to make sure we don't have 'thebb' reference
134
// already in the pool before adding it.
135

136                     for (int i = 0; i < itsPool.size() && refInPool == false; i++)
137                     {
138                          ByteBuffer JavaDoc tmpbb = (ByteBuffer JavaDoc)itsPool.get(i);
139                          if (thebb == tmpbb)
140                          {
141                              refInPool = true;
142                              bbAddr = System.identityHashCode(thebb);
143                          }
144                     }
145
146                 }
147
148                 // NOTE: The else part of this if will only get called
149
// if debug = true and refInPool = true, see logic above.
150
if (refInPool == false || debug == false)
151                 {
152                     // add ByteBuffer back to the pool
153
itsPool.add(thebb);
154                 }
155                 else // otherwise, log a stack trace with duplicate message
156
{
157                     String JavaDoc threadName = Thread.currentThread().getName();
158                     Throwable JavaDoc t =
159                             new Throwable JavaDoc(threadName +
160                                          ": Duplicate ByteBuffer reference (" +
161                                          bbAddr + ")");
162                     t.printStackTrace(System.out);
163                 }
164             }
165
166             // decrement the count of ByteBuffers released
167
// IMPORTANT: Since this counter is used only for information
168
// purposes, it does not use synchronized access.
169
itsObjectCounter--;
170         }
171         else
172         {
173             // ByteBuffer not pooled nor needed
174
thebb = null;
175         }
176     }
177
178
179     // Get a count of the outstanding allocated DirectByteBuffers.
180
// (Those allocated and have not been returned to the pool).
181
// IMPORTANT: Since this counter is used only for information
182
// purposes, it does not use synchronized access.
183
public int activeCount()
184     {
185          return itsObjectCounter;
186     }
187 }
188
189 // End of file.
190
Popular Tags