From ee55d34cfeed0f0e0430454ecef5a72679b279ab Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Tue, 22 Apr 2014 10:14:31 +0200 Subject: [PATCH] [#2414] Fix IllegalStateException when try to configure AbstractEpollChannel once it is deregistered Motivation: AbstractEpollChannel.clearEpollIn() throws an IllegalStateException if a user tries to change the autoRead configuration for the Channel and the Channel is not registered on an EventLoop yet. This makes it for example impossible to set AUTO_READ to false via the ServerBootstrap as the configuration is modifed before the Channel is registered. Modification: Check if the Channel is registered and if not just modify the flags directly so they are respected once the Channel is registered Result: It is possible now to configure AUTO_READ via the ServerBootstrap --- .../channel/epoll/AbstractEpollChannel.java | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/transport-native-epoll/src/main/java/io/netty/channel/epoll/AbstractEpollChannel.java b/transport-native-epoll/src/main/java/io/netty/channel/epoll/AbstractEpollChannel.java index 54da0beef2..35c8aecf00 100644 --- a/transport-native-epoll/src/main/java/io/netty/channel/epoll/AbstractEpollChannel.java +++ b/transport-native-epoll/src/main/java/io/netty/channel/epoll/AbstractEpollChannel.java @@ -105,21 +105,28 @@ abstract class AbstractEpollChannel extends AbstractChannel { } final void clearEpollIn() { - final EventLoop loop = eventLoop(); - final AbstractEpollUnsafe unsafe = (AbstractEpollUnsafe) unsafe(); - if (loop.inEventLoop()) { - unsafe.clearEpollIn0(); - } else { - // schedule a task to clear the EPOLLIN as it is not safe to modify it directly - loop.execute(new OneTimeTask() { - @Override - public void run() { - if (!config().isAutoRead() && !unsafe.readPending) { - // Still no read triggered so clear it now - unsafe.clearEpollIn0(); + // Only clear if registered with an EventLoop as otherwise + if (isRegistered()) { + final EventLoop loop = eventLoop(); + final AbstractEpollUnsafe unsafe = (AbstractEpollUnsafe) unsafe(); + if (loop.inEventLoop()) { + unsafe.clearEpollIn0(); + } else { + // schedule a task to clear the EPOLLIN as it is not safe to modify it directly + loop.execute(new OneTimeTask() { + @Override + public void run() { + if (!config().isAutoRead() && !unsafe.readPending) { + // Still no read triggered so clear it now + unsafe.clearEpollIn0(); + } } - } - }); + }); + } + } else { + // The EventLoop is not registered atm so just update the flags so the correct value + // will be used once the channel is registered + flags &= ~readFlag; } }