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 e83635aa3e..966cfc8345 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 @@ -202,6 +202,14 @@ final class EpollEventLoop extends SingleThreadEventLoop { break; } + // If a task was submitted when wakenUp value was 1, the task didn't get a chance to produce wakeup event. + // So we need to check task queue again before calling epoll_wait. If we don't, the task might be pended + // until epoll_wait was timed out. It might be pended until idle timeout if IdleStateHandler existed + // in pipeline. + if (hasTasks() && WAKEN_UP_UPDATER.compareAndSet(this, 0, 1)) { + return Native.epollWait(epollFd.intValue(), events, 0); + } + int selectedKeys = Native.epollWait(epollFd.intValue(), events, (int) timeoutMillis); selectCnt ++;