From e48b8f5c498b6f6e487f5a8d474b6066de7f1411 Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Fri, 10 Apr 2015 15:23:00 +0200 Subject: [PATCH] [#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. --- .../epoll/AbstractEpollStreamChannel.java | 10 +++++----- .../io/netty/channel/epoll/EpollEventLoop.java | 18 +++++++----------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/transport-native-epoll/src/main/java/io/netty/channel/epoll/AbstractEpollStreamChannel.java b/transport-native-epoll/src/main/java/io/netty/channel/epoll/AbstractEpollStreamChannel.java index 95d952212e..4988a8e422 100644 --- a/transport-native-epoll/src/main/java/io/netty/channel/epoll/AbstractEpollStreamChannel.java +++ b/transport-native-epoll/src/main/java/io/netty/channel/epoll/AbstractEpollStreamChannel.java @@ -569,11 +569,11 @@ public abstract class AbstractEpollStreamChannel extends AbstractEpollChannel { @Override void epollRdHupReady() { - if (isActive()) { - epollInReady(); - } else { - closeOnRead(pipeline()); - } + // Just call closeOnRead(). There is no need to trigger a read as this + // will result in an IOException anyway. + // + // See https://github.com/netty/netty/issues/3539 + closeOnRead(pipeline()); } @Override diff --git a/transport-native-epoll/src/main/java/io/netty/channel/epoll/EpollEventLoop.java b/transport-native-epoll/src/main/java/io/netty/channel/epoll/EpollEventLoop.java index b7ca2e29d2..b3bad00bcd 100644 --- a/transport-native-epoll/src/main/java/io/netty/channel/epoll/EpollEventLoop.java +++ b/transport-native-epoll/src/main/java/io/netty/channel/epoll/EpollEventLoop.java @@ -305,26 +305,22 @@ final class EpollEventLoop extends SingleThreadEventLoop { AbstractEpollChannel ch = channels.get(fd); 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(); - 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(); } - // We need to check if the channel is still open before try to trigger the - // 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()) { + if ((ev & Native.EPOLLOUT) != 0 && ch.isOpen()) { // force flush of data as the epoll is writable again unsafe.epollOutReady(); } - if (read && ch.isOpen()) { + + if ((ev & Native.EPOLLIN) != 0 && ch.isOpen()) { // Something is ready to read, so consume it now unsafe.epollInReady(); }