diff --git a/common/src/main/java/io/netty/util/concurrent/SingleThreadEventExecutor.java b/common/src/main/java/io/netty/util/concurrent/SingleThreadEventExecutor.java index aed8ad19b9..289026a7ce 100644 --- a/common/src/main/java/io/netty/util/concurrent/SingleThreadEventExecutor.java +++ b/common/src/main/java/io/netty/util/concurrent/SingleThreadEventExecutor.java @@ -658,11 +658,16 @@ public abstract class SingleThreadEventExecutor extends AbstractEventExecutor { } } - if (!addTaskWakesUp) { + if (!addTaskWakesUp && wakesUpForTask(task)) { wakeup(inEventLoop); } } + @SuppressWarnings("unused") + protected boolean wakesUpForTask(Runnable task) { + return true; + } + protected static void reject() { throw new RejectedExecutionException("event executor terminated"); } diff --git a/transport/src/main/java/io/netty/channel/DefaultChannelHandlerInvoker.java b/transport/src/main/java/io/netty/channel/DefaultChannelHandlerInvoker.java index 1dd54b1933..4174cb4c0b 100644 --- a/transport/src/main/java/io/netty/channel/DefaultChannelHandlerInvoker.java +++ b/transport/src/main/java/io/netty/channel/DefaultChannelHandlerInvoker.java @@ -383,7 +383,7 @@ public class DefaultChannelHandlerInvoker implements ChannelHandlerInvoker { } } - static final class WriteTask implements Runnable { + static final class WriteTask implements SingleThreadEventLoop.NonWakeupRunnable { private ChannelHandlerContext ctx; private Object msg; private ChannelPromise promise; @@ -391,7 +391,7 @@ public class DefaultChannelHandlerInvoker implements ChannelHandlerInvoker { private static final Recycler RECYCLER = new Recycler() { @Override - protected WriteTask newObject(Handle handle) { + protected WriteTask newObject(Handle handle) { return new WriteTask(handle); } }; @@ -406,9 +406,9 @@ public class DefaultChannelHandlerInvoker implements ChannelHandlerInvoker { return task; } - private final Recycler.Handle handle; + private final Recycler.Handle handle; - private WriteTask(Recycler.Handle handle) { + private WriteTask(Recycler.Handle handle) { this.handle = handle; } diff --git a/transport/src/main/java/io/netty/channel/SingleThreadEventLoop.java b/transport/src/main/java/io/netty/channel/SingleThreadEventLoop.java index 9b8f41932d..9d08aff420 100644 --- a/transport/src/main/java/io/netty/channel/SingleThreadEventLoop.java +++ b/transport/src/main/java/io/netty/channel/SingleThreadEventLoop.java @@ -50,4 +50,14 @@ public abstract class SingleThreadEventLoop extends SingleThreadEventExecutor im public ChannelHandlerInvoker asInvoker() { return invoker; } + + @Override + protected boolean wakesUpForTask(Runnable task) { + return !(task instanceof NonWakeupRunnable); + } + + /** + * Marker interface for {@linkRunnable} that will not trigger an {@link #wakeup(boolean)} in all cases. + */ + interface NonWakeupRunnable extends Runnable { } }