/** * Write bytes form the given {@link ByteBuf} to the underlying {@link java.nio.channels.Channel}. * * @param buf the {@link ByteBuf} from which the bytes should be written * @return amount the amount of written bytes */ private int doWriteBytes(ByteBuf buf, int readable) throws Exception { int readerIndex = buf.readerIndex(); int localFlushedAmount; if (buf.nioBufferCount() == 1) { if (buf.hasMemoryAddress()) { localFlushedAmount = Native.writeAddress(fd, buf.memoryAddress(), readerIndex, buf.writerIndex()); } else { ByteBuffer nioBuf = buf.internalNioBuffer(readerIndex, readable); localFlushedAmount = Native.write(fd, nioBuf, nioBuf.position(), nioBuf.limit()); } } else { // backed by more then one buffer, do a gathering write... ByteBuffer[] nioBufs = buf.nioBuffers(); localFlushedAmount = (int) Native.writev(fd, nioBufs, 0, nioBufs.length); } if (localFlushedAmount > 0) { buf.readerIndex(readerIndex + localFlushedAmount); } return localFlushedAmount; }
private void writeBytesMultiple( NioSocketChannelOutboundBuffer in, int msgCount, ByteBuffer[] nioBuffers) throws IOException { int nioBufferCnt = in.nioBufferCount(); long expectedWrittenBytes = in.nioBufferSize(); long localWrittenBytes = Native.writev(fd, nioBuffers, 0, nioBufferCnt); if (localWrittenBytes < expectedWrittenBytes) { setEpollOut(); // Did not write all buffers completely. // Release the fully written buffers and update the indexes of the partially written buffer. for (int i = msgCount; i > 0; i--) { final ByteBuf buf = (ByteBuf) in.current(); final int readerIndex = buf.readerIndex(); final int readableBytes = buf.writerIndex() - readerIndex; if (readableBytes < localWrittenBytes) { in.remove(); localWrittenBytes -= readableBytes; } else if (readableBytes > localWrittenBytes) { buf.readerIndex(readerIndex + (int) localWrittenBytes); in.progress(localWrittenBytes); break; } else { // readable == writtenBytes in.remove(); break; } } } else { // Release all buffers for (int i = msgCount; i > 0; i--) { in.remove(); } } }