Fix a bug where adaptive recvbuf size prediction doesn't work correctly when maxMessagesPerRead is > 1

This commit is contained in:
Trustin Lee 2013-12-21 19:56:36 +09:00
parent b889d3f559
commit 1fcd19a28f

View File

@ -110,8 +110,10 @@ public abstract class AbstractNioByteChannel extends AbstractNioChannel {
int messages = 0; int messages = 0;
boolean close = false; boolean close = false;
try { try {
int byteBufCapacity = allocHandle.guess();
int totalReadAmount = 0;
do { do {
byteBuf = allocHandle.allocate(allocator); byteBuf = allocator.ioBuffer(byteBufCapacity);
int writable = byteBuf.writableBytes(); int writable = byteBuf.writableBytes();
int localReadAmount = doReadBytes(byteBuf); int localReadAmount = doReadBytes(byteBuf);
if (localReadAmount <= 0) { if (localReadAmount <= 0) {
@ -120,16 +122,26 @@ public abstract class AbstractNioByteChannel extends AbstractNioChannel {
close = localReadAmount < 0; close = localReadAmount < 0;
break; break;
} }
pipeline.fireChannelRead(byteBuf); pipeline.fireChannelRead(byteBuf);
byteBuf = null; byteBuf = null;
allocHandle.record(localReadAmount);
if (totalReadAmount >= Integer.MAX_VALUE - localReadAmount) {
// Avoid overflow.
totalReadAmount = Integer.MAX_VALUE;
break;
}
totalReadAmount += localReadAmount;
if (localReadAmount < writable) { if (localReadAmount < writable) {
// we read less then what the buffer can hold so it seems like we drained it completely // Read less than what the buffer can hold,
// which might mean we drained the recv buffer completely.
break; break;
} }
} while (++ messages < maxMessagesPerRead); } while (++ messages < maxMessagesPerRead);
pipeline.fireChannelReadComplete(); pipeline.fireChannelReadComplete();
allocHandle.record(totalReadAmount);
if (close) { if (close) {
closeOnRead(pipeline); closeOnRead(pipeline);