- /*
- * @(#)ByteBufferPoolImpl.java 1.12 04/06/21
- *
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- */
-
- package com.sun.corba.se.impl.transport;
-
- import java.nio.ByteBuffer;
- import java.util.ArrayList;
-
- import com.sun.corba.se.spi.orb.ORB;
-
- import com.sun.corba.se.pept.transport.ByteBufferPool;
-
- /**
- * @author Charlie Hunt
- */
-
- public class ByteBufferPoolImpl implements ByteBufferPool
- {
- private ORB itsOrb;
- private int itsByteBufferSize;
- private ArrayList itsPool;
- private int itsObjectCounter = 0;
- private boolean debug;
-
- // Construct a ByteBufferPool for a pool of NIO ByteBuffers
- // of ORB fragment size.
- public ByteBufferPoolImpl(ORB theORB)
- {
- itsByteBufferSize = theORB.getORBData().getGIOPFragmentSize();
- itsPool = new ArrayList();
- itsOrb = theORB;
- debug = theORB.transportDebugFlag;
- }
-
- /*
- * Locations where ByteBuffers are gotten from the pool:
- * 1. ContactInfoBase.createMessageMediator()
- * 2. ByteBufferWithInfo.growBuffer()
- * 3. ByteBufferWithInfo(ORB, BufferManagerWrite) - constructor
- */
-
- // If the requested ByteBuffer size is less than or equal to
- // the ORB fragment size, and we have not disabled use of
- // direct byte buffers (normally for debugging purposes)
- // then get a DirectByteBuffer from the
- // pool if there is one, if there is not one in the pool,
- // then allocate a a DirectByteBuffer of ORB fragment size.
- //
- // If the request ByteBuffer size is greater than the ORB fragment
- // size, allocate a new non-direct ByteBuffer.
- public ByteBuffer getByteBuffer(int theAskSize)
- {
- ByteBuffer abb = null;
-
- if ((theAskSize <= itsByteBufferSize) &&
- !itsOrb.getORBData().disableDirectByteBufferUse())
- {
- // check if there's one in the pool, if not allocate one.
- int poolSize;
- synchronized (itsPool)
- {
- poolSize = itsPool.size();
- if (poolSize > 0)
- {
- abb = (ByteBuffer)itsPool.remove(poolSize - 1);
-
- // clear ByteBuffer before returning it
- abb.clear();
- }
- }
-
- // NOTE: Moved the 'else' part of the above if statement
- // outside the synchronized block since it is likely
- // less expensive to check poolSize than to allocate a
- // DirectByteBuffer in the synchronized block.
- if (poolSize <= 0)
- {
- abb = ByteBuffer.allocateDirect(itsByteBufferSize);
- }
-
- // increment the number of ByteBuffers gotten from pool
- // IMPORTANT: Since this counter is used only for information
- // purposes, it does not use synchronized access.
- itsObjectCounter++;
- }
- else
- {
- // Requested ByteBuffer size larger than the pool manages.
- // Just allocate a non-direct ByteBuffer
- abb = ByteBuffer.allocate(theAskSize);
- }
-
- return abb;
- }
-
-
- /*
- * Locations where ByteBuffers are released to the pool:
- * 1. ByteBufferWithInfo.growBuffer()
- * 2. BufferManagerWriteCollect.sendMessage()
- * 3. CDROutputStream_1_0.close()
- * 4. CDRInputStream_1_0.close()
- * 5. BufferManagerReadStream.underflow()
- * 6. BufferManagerWrite.close()
- * 7. BufferManagerRead.close()
- * 8. CorbaMessageMediatorImpl.releaseByteBufferToPool()
- */
-
- // If the ByteBuffer is a DirectByteBuffer, add it to the pool.
- // Otherwise, set its reference to null since it's not kept in
- // the pool and caller is saying he/she is done with it.
- // NOTE: The size of the ByteBuffer is not checked with the
- // this pool's ByteBuffer size since only DirectByteBuffers
- // ever allocated. Hence, only DirectByteBuffer are checked
- // here. An additional check could be added here for that though.
- public void releaseByteBuffer(ByteBuffer thebb)
- {
- if (thebb.isDirect())
- {
- synchronized (itsPool)
- {
- // use with debug to determine if byteBuffer is already
- // in the pool.
- boolean refInPool = false;
- int bbAddr = 0;
-
- if (debug)
- {
- // Check to make sure we don't have 'thebb' reference
- // already in the pool before adding it.
-
- for (int i = 0; i < itsPool.size() && refInPool == false; i++)
- {
- ByteBuffer tmpbb = (ByteBuffer)itsPool.get(i);
- if (thebb == tmpbb)
- {
- refInPool = true;
- bbAddr = System.identityHashCode(thebb);
- }
- }
-
- }
-
- // NOTE: The else part of this if will only get called
- // if debug = true and refInPool = true, see logic above.
- if (refInPool == false || debug == false)
- {
- // add ByteBuffer back to the pool
- itsPool.add(thebb);
- }
- else // otherwise, log a stack trace with duplicate message
- {
- String threadName = Thread.currentThread().getName();
- Throwable t =
- new Throwable(threadName +
- ": Duplicate ByteBuffer reference (" +
- bbAddr + ")");
- t.printStackTrace(System.out);
- }
- }
-
- // decrement the count of ByteBuffers released
- // IMPORTANT: Since this counter is used only for information
- // purposes, it does not use synchronized access.
- itsObjectCounter--;
- }
- else
- {
- // ByteBuffer not pooled nor needed
- thebb = null;
- }
- }
-
-
- // Get a count of the outstanding allocated DirectByteBuffers.
- // (Those allocated and have not been returned to the pool).
- // IMPORTANT: Since this counter is used only for information
- // purposes, it does not use synchronized access.
- public int activeCount()
- {
- return itsObjectCounter;
- }
- }
-
- // End of file.