Skip to content

Commit

Permalink
EPOLL RDHUP processing
Browse files Browse the repository at this point in the history
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 netty#6173.
  • Loading branch information
Scottmitch authored and liuzhengyang committed Sep 10, 2017
1 parent 36ae6dd commit 3b62783
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,13 @@ final void receivedRdHup() {
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) {
Expand All @@ -53,9 +58,7 @@ public final boolean continueReading() {
* 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();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ boolean maybeMoreDataToRead() {
/**
* 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());
}
}

0 comments on commit 3b62783

Please sign in to comment.