static void write( OioDatagramChannel channel, ChannelFuture future, Object message, SocketAddress remoteAddress) { try { ChannelBuffer buf = (ChannelBuffer) message; int length = buf.readableBytes(); ByteBuffer nioBuf = buf.toByteBuffer(); DatagramPacket packet; if (nioBuf.hasArray()) { // Avoid copy if the buffer is backed by an array. packet = new DatagramPacket(nioBuf.array(), nioBuf.arrayOffset(), length); } else { // Otherwise it will be expensive. byte[] arrayBuf = new byte[length]; buf.getBytes(0, arrayBuf); packet = new DatagramPacket(arrayBuf, length); } if (remoteAddress != null) { packet.setSocketAddress(remoteAddress); } channel.socket.send(packet); fireWriteComplete(channel, length); future.setSuccess(); } catch (Throwable t) { future.setFailure(t); fireExceptionCaught(channel, t); } }
private static void writeNow(NioSocketChannel channel, int writeSpinCount) { boolean open = true; boolean addOpWrite = false; boolean removeOpWrite = false; MessageEvent evt; ChannelBuffer buf; int bufIdx; int writtenBytes = 0; Queue<MessageEvent> writeBuffer = channel.writeBuffer; synchronized (channel.writeLock) { channel.inWriteNowLoop = true; evt = channel.currentWriteEvent; for (; ; ) { if (evt == null) { evt = writeBuffer.poll(); if (evt == null) { channel.currentWriteEvent = null; removeOpWrite = true; break; } evt = consolidateComposite(evt); buf = (ChannelBuffer) evt.getMessage(); bufIdx = buf.readerIndex(); } else { buf = (ChannelBuffer) evt.getMessage(); bufIdx = channel.currentWriteIndex; } try { for (int i = writeSpinCount; i > 0; i--) { int localWrittenBytes = buf.getBytes(bufIdx, channel.socket, buf.writerIndex() - bufIdx); if (localWrittenBytes != 0) { bufIdx += localWrittenBytes; writtenBytes += localWrittenBytes; break; } } if (bufIdx == buf.writerIndex()) { // Successful write - proceed to the next message. channel.currentWriteEvent = null; evt.getFuture().setSuccess(); evt = null; } else { // Not written fully - perhaps the kernel buffer is full. channel.currentWriteEvent = evt; channel.currentWriteIndex = bufIdx; addOpWrite = true; break; } } catch (AsynchronousCloseException e) { // Doesn't need a user attention - ignore. channel.currentWriteEvent = evt; channel.currentWriteIndex = bufIdx; } catch (Throwable t) { channel.currentWriteEvent = null; evt.getFuture().setFailure(t); evt = null; fireExceptionCaught(channel, t); if (t instanceof IOException) { open = false; close(channel, succeededFuture(channel)); } } } channel.inWriteNowLoop = false; } fireWriteComplete(channel, writtenBytes); if (open) { if (addOpWrite) { setOpWrite(channel); } else if (removeOpWrite) { clearOpWrite(channel); } } }