diff --git a/common/src/main/java/io/netty/util/concurrent/DefaultPromise.java b/common/src/main/java/io/netty/util/concurrent/DefaultPromise.java index 1a3ed0502d..6bae138e78 100644 --- a/common/src/main/java/io/netty/util/concurrent/DefaultPromise.java +++ b/common/src/main/java/io/netty/util/concurrent/DefaultPromise.java @@ -836,7 +836,8 @@ public class DefaultPromise extends AbstractFuture implements Promise { @Override public void run() { - if (listeners == null) { + final EventExecutor executor = executor(); + if (listeners == null || executor == ImmediateEventExecutor.INSTANCE) { for (;;) { GenericFutureListener l = poll(); if (l == null) { @@ -847,7 +848,7 @@ public class DefaultPromise extends AbstractFuture implements Promise { } else { // Reschedule until the initial notification is done to avoid the race condition // where the notification is made in an incorrect order. - execute(executor(), this); + execute(executor, this); } } } diff --git a/common/src/test/java/io/netty/util/concurrent/DefaultPromiseTest.java b/common/src/test/java/io/netty/util/concurrent/DefaultPromiseTest.java index dd971c8149..fc413e492e 100644 --- a/common/src/test/java/io/netty/util/concurrent/DefaultPromiseTest.java +++ b/common/src/test/java/io/netty/util/concurrent/DefaultPromiseTest.java @@ -142,6 +142,38 @@ public class DefaultPromiseTest { testListenerNotifyLater(2); } + @Test(timeout = 2000) + public void testPromiseListenerAddWhenCompleteFailure() throws Exception { + testPromiseListenerAddWhenComplete(new RuntimeException()); + } + + @Test(timeout = 2000) + public void testPromiseListenerAddWhenCompleteSuccess() throws Exception { + testPromiseListenerAddWhenComplete(null); + } + + private static void testPromiseListenerAddWhenComplete(Throwable cause) throws InterruptedException { + final CountDownLatch latch = new CountDownLatch(1); + final Promise promise = new DefaultPromise(ImmediateEventExecutor.INSTANCE); + promise.addListener(new FutureListener() { + @Override + public void operationComplete(Future future) throws Exception { + promise.addListener(new FutureListener() { + @Override + public void operationComplete(Future future) throws Exception { + latch.countDown(); + } + }); + } + }); + if (cause == null) { + promise.setSuccess(null); + } else { + promise.setFailure(cause); + } + latch.await(); + } + private static void testListenerNotifyLater(final int numListenersBefore) throws Exception { EventExecutor executor = new TestEventExecutor(); int expectedCount = numListenersBefore + 2;