- /*
- * @(#)BufferManagerWriteCollect.java 1.14 03/12/19
- *
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- */
- package com.sun.corba.se.impl.encoding;
-
- import java.nio.ByteBuffer;
- import java.util.Iterator;
- import java.util.NoSuchElementException;
- import java.util.LinkedList;
-
- import com.sun.corba.se.impl.encoding.BufferQueue;
- import com.sun.corba.se.impl.encoding.BufferManagerWrite;
- import com.sun.corba.se.impl.orbutil.ORBConstants;
- import com.sun.corba.se.impl.protocol.giopmsgheaders.Message;
- import com.sun.corba.se.impl.encoding.ByteBufferWithInfo;
- import com.sun.corba.se.impl.protocol.giopmsgheaders.MessageBase;
- import com.sun.corba.se.impl.protocol.giopmsgheaders.FragmentMessage;
- import com.sun.corba.se.spi.orb.ORB;
- import com.sun.corba.se.impl.encoding.CDROutputObject;
- import com.sun.corba.se.impl.orbutil.ORBUtility;
- import com.sun.corba.se.pept.transport.Connection;
- import com.sun.corba.se.pept.transport.ByteBufferPool;
- import com.sun.corba.se.pept.encoding.OutputObject;
-
- /**
- * Collect buffer manager.
- */
- public class BufferManagerWriteCollect extends BufferManagerWrite
- {
- private BufferQueue queue = new BufferQueue();
-
- private boolean sentFragment = false;
- private boolean debug = false;
-
-
- BufferManagerWriteCollect(ORB orb)
- {
- super(orb);
- if (orb != null)
- debug = orb.transportDebugFlag;
- }
-
- public boolean sentFragment() {
- return sentFragment;
- }
-
- /**
- * Returns the correct buffer size for this type of
- * buffer manager as set in the ORB.
- */
- public int getBufferSize() {
- return orb.getORBData().getGIOPFragmentSize();
- }
-
- // Set the fragment's "more fragments" bit to true, put it in the
- // queue, and allocate a new bbwi.
- public void overflow (ByteBufferWithInfo bbwi)
- {
- // Set the fragment's moreFragments field to true
- MessageBase.setFlag(bbwi.byteBuffer, Message.MORE_FRAGMENTS_BIT);
-
- // Enqueue the previous fragment
- queue.enqueue(bbwi);
-
- // Create a new bbwi
- ByteBufferWithInfo newBbwi = new ByteBufferWithInfo(orb, this);
- newBbwi.fragmented = true;
-
- // XREVISIT - Downcast
- ((CDROutputObject)outputObject).setByteBufferWithInfo(newBbwi);
-
- // Now we must marshal in the fragment header/GIOP header
-
- // REVISIT - we can optimize this by not creating the fragment message
- // each time.
-
- // XREVISIT - Downcast
- FragmentMessage header =
- ((CDROutputObject)outputObject).getMessageHeader()
- .createFragmentMessage();
-
- header.write((CDROutputObject)outputObject);
- }
-
- // Send all fragments
- public void sendMessage ()
- {
- // Enqueue the last fragment
- queue.enqueue(((CDROutputObject)outputObject).getByteBufferWithInfo());
-
- Iterator bufs = iterator();
-
- Connection conn =
- ((OutputObject)outputObject).getMessageMediator().
- getConnection();
-
- // With the collect strategy, we must lock the connection
- // while fragments are being sent. This is so that there are
- // no interleved fragments in GIOP 1.1.
- //
- // Note that this thread must not call writeLock again in any
- // of its send methods!
- conn.writeLock();
-
- try {
-
- // Get a reference to ByteBufferPool so that the ByteBufferWithInfo
- // ByteBuffer can be released to the ByteBufferPool
- ByteBufferPool byteBufferPool = orb.getByteBufferPool();
-
- while (bufs.hasNext()) {
-
- ByteBufferWithInfo bbwi = (ByteBufferWithInfo)bufs.next();
- ((CDROutputObject)outputObject).setByteBufferWithInfo(bbwi);
-
- conn.sendWithoutLock(((CDROutputObject)outputObject));
-
- sentFragment = true;
-
- // Release ByteBufferWithInfo's ByteBuffer back to the pool
- // of ByteBuffers.
- if (debug)
- {
- // print address of ByteBuffer being released
- int bbAddress = System.identityHashCode(bbwi.byteBuffer);
- StringBuffer sb = new StringBuffer(80);
- sb.append("sendMessage() - releasing ByteBuffer id (");
- sb.append(bbAddress).append(") to ByteBufferPool.");
- String msg = sb.toString();
- dprint(msg);
- }
- byteBufferPool.releaseByteBuffer(bbwi.byteBuffer);
- bbwi.byteBuffer = null;
- bbwi = null;
- }
-
- sentFullMessage = true;
-
- } finally {
-
- conn.writeUnlock();
- }
- }
-
- /**
- * Close the BufferManagerWrite - do any outstanding cleanup.
- *
- * For a BufferManagerWriteGrow any queued ByteBufferWithInfo must
- * have its ByteBuffer released to the ByteBufferPool.
- */
- public void close()
- {
- // iterate thru queue and release any ByteBufferWithInfo's
- // ByteBuffer that may be remaining on the queue to the
- // ByteBufferPool.
-
- Iterator bufs = iterator();
-
- ByteBufferPool byteBufferPool = orb.getByteBufferPool();
-
- while (bufs.hasNext())
- {
- ByteBufferWithInfo bbwi = (ByteBufferWithInfo)bufs.next();
- if (bbwi != null && bbwi.byteBuffer != null)
- {
- if (debug)
- {
- // print address of ByteBuffer being released
- int bbAddress = System.identityHashCode(bbwi.byteBuffer);
- StringBuffer sb = new StringBuffer(80);
- sb.append("close() - releasing ByteBuffer id (");
- sb.append(bbAddress).append(") to ByteBufferPool.");
- String msg = sb.toString();
- dprint(msg);
- }
- byteBufferPool.releaseByteBuffer(bbwi.byteBuffer);
- bbwi.byteBuffer = null;
- bbwi = null;
- }
- }
- }
-
- private void dprint(String msg)
- {
- ORBUtility.dprint("BufferManagerWriteCollect", msg);
- }
-
- private Iterator iterator ()
- {
- return new BufferManagerWriteCollectIterator();
- }
-
- private class BufferManagerWriteCollectIterator implements Iterator
- {
- public boolean hasNext ()
- {
- return queue.size() != 0;
- }
-
- public Object next ()
- {
- return queue.dequeue();
- }
-
- public void remove ()
- {
- throw new UnsupportedOperationException();
- }
- }
- }