From 0bc93dda081499dfe4f96a1507d24fa46bf0f31f Mon Sep 17 00:00:00 2001 From: Scott Mitchell Date: Thu, 7 Apr 2016 19:49:02 -0700 Subject: [PATCH] NIO autoReadClear should also clear the SelectionKey Motivation: Prior to 5b48fc284ebe85ca4974985e3be005d37626e980 setting readPending to false when autoReadClear was called was enough because when/if the EventLoop woke up with a read event we would first check if readPending was true and if it is not, we would return early. Now that readPending will only be set in the EventLoop it is not necessary to check readPending at the start of the read methods, and we should instead remove the OP_READ from the SelectionKey when we also set readPending to false. Modifications: - autoReadCleared should call AbstractNioUnsafe.removeReadOp Result: NIO is now consistent with EPOLL and removes the READ operation on the selector when autoRead is cleared. --- .../netty/channel/nio/AbstractNioChannel.java | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/transport/src/main/java/io/netty/channel/nio/AbstractNioChannel.java b/transport/src/main/java/io/netty/channel/nio/AbstractNioChannel.java index 981f7c8b15..d69358167b 100644 --- a/transport/src/main/java/io/netty/channel/nio/AbstractNioChannel.java +++ b/transport/src/main/java/io/netty/channel/nio/AbstractNioChannel.java @@ -65,7 +65,7 @@ public abstract class AbstractNioChannel extends AbstractChannel { private final Runnable clearReadPendingRunnable = new Runnable() { @Override public void run() { - readPending = false; + clearReadPending0(); } }; @@ -149,17 +149,17 @@ public abstract class AbstractNioChannel extends AbstractChannel { if (isRegistered()) { EventLoop eventLoop = eventLoop(); if (eventLoop.inEventLoop()) { - this.readPending = readPending; + setReadPending0(readPending); } else { eventLoop.execute(new OneTimeTask() { @Override public void run() { - AbstractNioChannel.this.readPending = readPending; + setReadPending0(readPending); } }); } } else { - this.readPending = readPending; + setReadPending0(readPending); } } @@ -170,16 +170,28 @@ public abstract class AbstractNioChannel extends AbstractChannel { if (isRegistered()) { EventLoop eventLoop = eventLoop(); if (eventLoop.inEventLoop()) { - readPending = false; + clearReadPending0(); } else { eventLoop.execute(clearReadPendingRunnable); } } else { // Best effort if we are not registered yet clear readPending. This happens during channel initialization. - readPending = false; + clearReadPending0(); } } + private void setReadPending0(boolean readPending) { + this.readPending = readPending; + if (!readPending) { + ((AbstractNioUnsafe) unsafe()).removeReadOp(); + } + } + + private void clearReadPending0() { + readPending = false; + ((AbstractNioUnsafe) unsafe()).removeReadOp(); + } + /** * Return {@code true} if the input of this {@link Channel} is shutdown */