BufferManagerWriteCollect.java revision 608:7e06bf1dcb09
1/* 2 * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25package com.sun.corba.se.impl.encoding; 26 27import java.nio.ByteBuffer; 28import java.util.Iterator; 29import java.util.NoSuchElementException; 30import java.util.LinkedList; 31 32import com.sun.corba.se.impl.encoding.BufferQueue; 33import com.sun.corba.se.impl.encoding.BufferManagerWrite; 34import com.sun.corba.se.impl.orbutil.ORBConstants; 35import com.sun.corba.se.impl.protocol.giopmsgheaders.Message; 36import com.sun.corba.se.impl.encoding.ByteBufferWithInfo; 37import com.sun.corba.se.impl.protocol.giopmsgheaders.MessageBase; 38import com.sun.corba.se.impl.protocol.giopmsgheaders.FragmentMessage; 39import com.sun.corba.se.spi.orb.ORB; 40import com.sun.corba.se.impl.encoding.CDROutputObject; 41import com.sun.corba.se.impl.orbutil.ORBUtility; 42import com.sun.corba.se.pept.transport.Connection; 43import com.sun.corba.se.pept.transport.ByteBufferPool; 44import com.sun.corba.se.pept.encoding.OutputObject; 45 46/** 47 * Collect buffer manager. 48 */ 49public class BufferManagerWriteCollect extends BufferManagerWrite 50{ 51 private BufferQueue queue = new BufferQueue(); 52 53 private boolean sentFragment = false; 54 private boolean debug = false; 55 56 57 BufferManagerWriteCollect(ORB orb) 58 { 59 super(orb); 60 if (orb != null) 61 debug = orb.transportDebugFlag; 62 } 63 64 public boolean sentFragment() { 65 return sentFragment; 66 } 67 68 /** 69 * Returns the correct buffer size for this type of 70 * buffer manager as set in the ORB. 71 */ 72 public int getBufferSize() { 73 return orb.getORBData().getGIOPFragmentSize(); 74 } 75 76 // Set the fragment's "more fragments" bit to true, put it in the 77 // queue, and allocate a new bbwi. 78 public void overflow (ByteBufferWithInfo bbwi) 79 { 80 // Set the fragment's moreFragments field to true 81 MessageBase.setFlag(bbwi.byteBuffer, Message.MORE_FRAGMENTS_BIT); 82 83 // Enqueue the previous fragment 84 queue.enqueue(bbwi); 85 86 // Create a new bbwi 87 ByteBufferWithInfo newBbwi = new ByteBufferWithInfo(orb, this); 88 newBbwi.fragmented = true; 89 90 // XREVISIT - Downcast 91 ((CDROutputObject)outputObject).setByteBufferWithInfo(newBbwi); 92 93 // Now we must marshal in the fragment header/GIOP header 94 95 // REVISIT - we can optimize this by not creating the fragment message 96 // each time. 97 98 // XREVISIT - Downcast 99 FragmentMessage header = 100 ((CDROutputObject)outputObject).getMessageHeader() 101 .createFragmentMessage(); 102 103 header.write((CDROutputObject)outputObject); 104 } 105 106 // Send all fragments 107 public void sendMessage () 108 { 109 // Enqueue the last fragment 110 queue.enqueue(((CDROutputObject)outputObject).getByteBufferWithInfo()); 111 112 Iterator bufs = iterator(); 113 114 Connection conn = 115 ((OutputObject)outputObject).getMessageMediator(). 116 getConnection(); 117 118 // With the collect strategy, we must lock the connection 119 // while fragments are being sent. This is so that there are 120 // no interleved fragments in GIOP 1.1. 121 // 122 // Note that this thread must not call writeLock again in any 123 // of its send methods! 124 conn.writeLock(); 125 126 try { 127 128 // Get a reference to ByteBufferPool so that the ByteBufferWithInfo 129 // ByteBuffer can be released to the ByteBufferPool 130 ByteBufferPool byteBufferPool = orb.getByteBufferPool(); 131 132 while (bufs.hasNext()) { 133 134 ByteBufferWithInfo bbwi = (ByteBufferWithInfo)bufs.next(); 135 ((CDROutputObject)outputObject).setByteBufferWithInfo(bbwi); 136 137 conn.sendWithoutLock(((CDROutputObject)outputObject)); 138 139 sentFragment = true; 140 141 // Release ByteBufferWithInfo's ByteBuffer back to the pool 142 // of ByteBuffers. 143 if (debug) 144 { 145 // print address of ByteBuffer being released 146 int bbAddress = System.identityHashCode(bbwi.byteBuffer); 147 StringBuffer sb = new StringBuffer(80); 148 sb.append("sendMessage() - releasing ByteBuffer id ("); 149 sb.append(bbAddress).append(") to ByteBufferPool."); 150 String msg = sb.toString(); 151 dprint(msg); 152 } 153 byteBufferPool.releaseByteBuffer(bbwi.byteBuffer); 154 bbwi.byteBuffer = null; 155 bbwi = null; 156 } 157 158 sentFullMessage = true; 159 160 } finally { 161 162 conn.writeUnlock(); 163 } 164 } 165 166 /** 167 * Close the BufferManagerWrite - do any outstanding cleanup. 168 * 169 * For a BufferManagerWriteGrow any queued ByteBufferWithInfo must 170 * have its ByteBuffer released to the ByteBufferPool. 171 */ 172 public void close() 173 { 174 // iterate thru queue and release any ByteBufferWithInfo's 175 // ByteBuffer that may be remaining on the queue to the 176 // ByteBufferPool. 177 178 Iterator bufs = iterator(); 179 180 ByteBufferPool byteBufferPool = orb.getByteBufferPool(); 181 182 while (bufs.hasNext()) 183 { 184 ByteBufferWithInfo bbwi = (ByteBufferWithInfo)bufs.next(); 185 if (bbwi != null && bbwi.byteBuffer != null) 186 { 187 if (debug) 188 { 189 // print address of ByteBuffer being released 190 int bbAddress = System.identityHashCode(bbwi.byteBuffer); 191 StringBuffer sb = new StringBuffer(80); 192 sb.append("close() - releasing ByteBuffer id ("); 193 sb.append(bbAddress).append(") to ByteBufferPool."); 194 String msg = sb.toString(); 195 dprint(msg); 196 } 197 byteBufferPool.releaseByteBuffer(bbwi.byteBuffer); 198 bbwi.byteBuffer = null; 199 bbwi = null; 200 } 201 } 202 } 203 204 private void dprint(String msg) 205 { 206 ORBUtility.dprint("BufferManagerWriteCollect", msg); 207 } 208 209 private Iterator iterator () 210 { 211 return new BufferManagerWriteCollectIterator(); 212 } 213 214 private class BufferManagerWriteCollectIterator implements Iterator 215 { 216 public boolean hasNext () 217 { 218 return queue.size() != 0; 219 } 220 221 public Object next () 222 { 223 return queue.dequeue(); 224 } 225 226 public void remove () 227 { 228 throw new UnsupportedOperationException(); 229 } 230 } 231} 232