[#3539] Correctly handle EPOLLRDHUP

Motivation:

As we missed to correctly handle EPOLLRDHUP we produce an IOException which is unnessary. This leads
to have exceptionCaught(...) methods called.

Modifications:

When EPOLLRDHUP was received just close the socket and fail all pending writes.

Result:

Correctly handle of EPOLLRDHUP and so not miss-leading exceptions.
This commit is contained in:
Norman Maurer 2015-04-10 15:23:00 +02:00
parent a5eb2e66d2
commit acb6902f68
2 changed files with 12 additions and 16 deletions

View File

@ -569,12 +569,12 @@ public abstract class AbstractEpollStreamChannel extends AbstractEpollChannel {
@Override @Override
void epollRdHupReady() { void epollRdHupReady() {
if (isActive()) { // Just call closeOnRead(). There is no need to trigger a read as this
epollInReady(); // will result in an IOException anyway.
} else { //
// See https://github.com/netty/netty/issues/3539
closeOnRead(pipeline()); closeOnRead(pipeline());
} }
}
@Override @Override
void epollInReady() { void epollInReady() {

View File

@ -307,26 +307,22 @@ final class EpollEventLoop extends SingleThreadEventLoop {
AbstractEpollChannel ch = channels.get(fd); AbstractEpollChannel ch = channels.get(fd);
if (ch != null && ch.isOpen()) { if (ch != null && ch.isOpen()) {
boolean close = (ev & Native.EPOLLRDHUP) != 0;
boolean read = (ev & Native.EPOLLIN) != 0;
boolean write = (ev & Native.EPOLLOUT) != 0;
AbstractEpollUnsafe unsafe = (AbstractEpollUnsafe) ch.unsafe(); AbstractEpollUnsafe unsafe = (AbstractEpollUnsafe) ch.unsafe();
if (close) { // We need to check if the channel is still open before try to trigger the
// callbacks.
// See https://github.com/netty/netty/issues/3443
if ((ev & Native.EPOLLRDHUP) != 0 && ch.isOpen()) {
unsafe.epollRdHupReady(); unsafe.epollRdHupReady();
} }
// We need to check if the channel is still open before try to trigger the if ((ev & Native.EPOLLOUT) != 0 && ch.isOpen()) {
// callbacks as otherwise we may trigger an IllegalStateException when try
// to access the file descriptor.
//
// See https://github.com/netty/netty/issues/3443
if (write && ch.isOpen()) {
// force flush of data as the epoll is writable again // force flush of data as the epoll is writable again
unsafe.epollOutReady(); unsafe.epollOutReady();
} }
if (read && ch.isOpen()) {
if ((ev & Native.EPOLLIN) != 0 && ch.isOpen()) {
// Something is ready to read, so consume it now // Something is ready to read, so consume it now
unsafe.epollInReady(); unsafe.epollInReady();
} }