EPOLL RDHUP processing

Motivation:
EpollRecvByteAllocatorHandle will read unconditionally if EPOLLRDHUP has been received. However we can just treat this the same was we do as data maybe pending in ET mode, and let LT mode notify us if we haven't read all data.

Modifications:
- EpollRecvByteAllocatorHandle should not always force a read just because EPOLLRDHUP has been received, but just treated as an indicator that there maybe more data to read in ET mode

Result:
Fixes https://github.com/netty/netty/issues/6173.
This commit is contained in:
Scott Mitchell 2017-01-07 01:04:29 -08:00
parent 583a59abb1
commit 631077c793
2 changed files with 10 additions and 5 deletions

View File

@ -32,8 +32,13 @@ class EpollRecvByteAllocatorHandle extends RecvByteBufAllocator.DelegatingHandle
receivedRdHup = true;
}
final boolean isReceivedRdHup() {
return receivedRdHup;
}
boolean maybeMoreDataToRead() {
return isEdgeTriggered && lastBytesRead() > 0;
// If EPOLLRDHUP has been received we must read until we get a read error.
return isEdgeTriggered && (lastBytesRead() > 0 || receivedRdHup);
}
final void edgeTriggered(boolean edgeTriggered) {
@ -53,9 +58,7 @@ class EpollRecvByteAllocatorHandle extends RecvByteBufAllocator.DelegatingHandle
* continue to avoid a {@link StackOverflowError} between channelReadComplete and reading from the
* channel. It is expected that the {@link #EpollSocketChannel} implementations will track if we are in
* edgeTriggered mode and all data was not read, and will force a EPOLLIN ready event.
*
* If EPOLLRDHUP has been received we must read until we get a read error.
*/
return receivedRdHup || maybeMoreDataToRead() && config.isAutoRead() || super.continueReading();
return maybeMoreDataToRead() && config.isAutoRead() || super.continueReading();
}
}

View File

@ -28,7 +28,9 @@ final class EpollRecvByteAllocatorStreamingHandle extends EpollRecvByteAllocator
/**
* For stream oriented descriptors we can assume we are done reading if the last read attempt didn't produce
* a full buffer (see Q9 in <a href="http://man7.org/linux/man-pages/man7/epoll.7.html">epoll man</a>).
*
* If EPOLLRDHUP has been received we must read until we get a read error.
*/
return isEdgeTriggered() && lastBytesRead() == attemptedBytesRead();
return isEdgeTriggered() && (lastBytesRead() == attemptedBytesRead() || isReceivedRdHup());
}
}