Overall clean-up in EpollSocketChannel

- Extract writev part from doWrite() for simplicity
- Clearer comments
This commit is contained in:
Trustin Lee 2014-02-17 05:21:10 -08:00
parent 8f3c09ba6b
commit 91da8e228b

View File

@ -128,31 +128,8 @@ public final class EpollSocketChannel extends AbstractEpollChannel implements So
return localFlushedAmount; return localFlushedAmount;
} }
/** private void writeBytesMultiple(
* Write a {@link DefaultFileRegion} ChannelOutboundBuffer in, int msgCount, ByteBuffer[] nioBuffers) throws IOException {
*
* @param region the {@link DefaultFileRegion} from which the bytes should be written
* @return amount the amount of written bytes
*/
private long doWriteFileRegion(DefaultFileRegion region, long count) throws Exception {
return Native.sendfile(fd, region, region.transfered(), count);
}
@Override
protected void doWrite(ChannelOutboundBuffer in) throws Exception {
for (;;) {
final int msgCount = in.size();
if (msgCount == 0) {
// Wrote all messages.
clearEpollOut();
break;
}
// Do non-gathering write for a single buffer case.
if (msgCount > 1) {
// Ensure the pending writes are made of ByteBufs only.
ByteBuffer[] nioBuffers = in.nioBuffers();
if (nioBuffers != null) {
int nioBufferCnt = in.nioBufferCount(); int nioBufferCnt = in.nioBufferCount();
long expectedWrittenBytes = in.nioBufferSize(); long expectedWrittenBytes = in.nioBufferSize();
@ -188,11 +165,46 @@ public final class EpollSocketChannel extends AbstractEpollChannel implements So
in.remove(); in.remove();
} }
} }
// try again as a ChannelFuture may be notified in the meantime and triggered another flush }
/**
* Write a {@link DefaultFileRegion}
*
* @param region the {@link DefaultFileRegion} from which the bytes should be written
* @return amount the amount of written bytes
*/
private long doWriteFileRegion(DefaultFileRegion region, long count) throws Exception {
return Native.sendfile(fd, region, region.transfered(), count);
}
@Override
protected void doWrite(ChannelOutboundBuffer in) throws Exception {
for (;;) {
final int msgCount = in.size();
if (msgCount == 0) {
// Wrote all messages.
clearEpollOut();
break;
}
// Do gathering write if:
// * the outbound buffer contains more than one messages and
// * they are all buffers rather than a file region.
if (msgCount > 1) {
// Ensure the pending writes are made of ByteBufs only.
ByteBuffer[] nioBuffers = in.nioBuffers();
if (nioBuffers != null) {
writeBytesMultiple(in, msgCount, nioBuffers);
// We do not break the loop here even if the outbound buffer was flushed completely,
// because a user might have triggered another write and flush when we notify his or her
// listeners.
continue; continue;
} }
} }
// The outbound buffer contains only one message or it contains a file region.
Object msg = in.current(); Object msg = in.current();
if (msg instanceof ByteBuf) { if (msg instanceof ByteBuf) {
ByteBuf buf = (ByteBuf) msg; ByteBuf buf = (ByteBuf) msg;