From 0cb4cc4e498afe8a44aede3f5bec10ec477a4536 Mon Sep 17 00:00:00 2001 From: Chris Vest Date: Thu, 2 Sep 2021 10:46:54 +0200 Subject: [PATCH] Make Promise not extend Future (#11634) Motivation: We wish to separate these two into clearer write/read interfaces. In particular, we don't want to be able to add listeners to promises, because it makes it easy to add them out of order. We can't prevent it entirely, because any promise can be freely converted to a future where listeners can be added. We can, however, discourage this in the API. Modification: The Promise interface no longer extends the Future interface. Numerous changes to make the project compile and its tests run. Result: Clearer separation of concerns in the code. --- .../websocketx/WebSocketClientHandshaker.java | 4 +- ...bSocketClientProtocolHandshakeHandler.java | 4 +- .../websocketx/WebSocketProtocolHandler.java | 9 +- .../websocketx/WebSocketServerHandshaker.java | 2 +- ...bSocketServerProtocolHandshakeHandler.java | 3 +- .../http/HttpServerUpgradeHandlerTest.java | 4 +- .../WebSocketProtocolHandlerTest.java | 2 +- .../http2/AbstractHttp2StreamChannel.java | 4 +- .../CompressorHttp2ConnectionEncoder.java | 2 +- .../codec/http2/DefaultHttp2Connection.java | 2 +- .../http2/DefaultHttp2ConnectionEncoder.java | 12 +- .../handler/codec/http2/Http2CodecUtil.java | 14 +- .../codec/http2/Http2ConnectionHandler.java | 2 +- .../http2/Http2StreamChannelBootstrap.java | 4 +- .../http2/HttpToHttp2ConnectionHandler.java | 2 +- .../codec/http2/StreamBufferingEncoder.java | 4 +- .../http2/DefaultHttp2ConnectionTest.java | 15 +- .../http2/Http2ConnectionHandlerTest.java | 8 +- .../http2/Http2ConnectionRoundtripTest.java | 14 +- .../Http2ControlFrameLimitEncoderTest.java | 14 +- .../codec/http2/Http2FrameCodecTest.java | 2 +- .../codec/http2/Http2FrameRoundtripTest.java | 4 +- .../codec/http2/Http2MultiplexTest.java | 5 +- .../Http2StreamChannelBootstrapTest.java | 4 +- .../http2/StreamBufferingEncoderTest.java | 11 +- .../codec/MessageToMessageEncoder.java | 2 +- .../codec/compression/Bzip2Encoder.java | 4 +- .../codec/compression/JdkZlibEncoder.java | 4 +- .../codec/compression/Lz4FrameEncoder.java | 4 +- .../concurrent/AbstractEventExecutor.java | 7 +- .../AbstractScheduledEventExecutor.java | 5 + .../util/concurrent/AsynchronousResult.java | 96 +++++++++++ .../DefaultFutureCompletionStage.java | 20 +-- .../netty/util/concurrent/DefaultPromise.java | 16 +- .../java/io/netty/util/concurrent/Future.java | 38 +---- .../concurrent/FutureCompletionStage.java | 6 +- .../io/netty/util/concurrent/Futures.java | 16 +- .../util/concurrent/GlobalEventExecutor.java | 2 +- .../concurrent/ImmediateEventExecutor.java | 2 +- .../MultithreadEventExecutorGroup.java | 2 +- .../io/netty/util/concurrent/Promise.java | 36 ++-- .../concurrent/RunnableFutureAdapter.java | 33 ++-- .../RunnableScheduledFutureAdapter.java | 35 ++-- .../concurrent/SingleThreadEventExecutor.java | 4 +- .../util/concurrent/UnaryPromiseNotifier.java | 2 +- .../UnorderedThreadPoolEventExecutor.java | 7 +- .../internal/PromiseNotificationUtil.java | 2 +- .../DefaultFutureCompletionStageTest.java | 6 +- .../io/netty/util/concurrent/FuturesTest.java | 17 +- .../util/concurrent/PromiseCombinerTest.java | 154 ++++++------------ .../SingleThreadEventExecutorTest.java | 2 +- .../client/WebSocketClientHandler.java | 2 +- .../client/Http2SettingsHandler.java | 2 +- .../client/HttpResponseHandler.java | 2 +- .../netty/example/ocsp/OcspClientExample.java | 2 +- .../netty/example/smtp/SmtpClientHandler.java | 2 +- .../socksproxy/SocksServerConnectHandler.java | 68 ++++---- .../io/netty/handler/proxy/ProxyHandler.java | 4 +- .../handler/proxy/HttpProxyHandlerTest.java | 7 +- .../address/ResolveAddressHandler.java | 8 +- .../java/io/netty/handler/ssl/SniHandler.java | 4 +- .../java/io/netty/handler/ssl/SslHandler.java | 34 ++-- .../handler/stream/ChunkedWriteHandler.java | 10 +- .../AbstractTrafficShapingHandler.java | 4 +- .../GlobalChannelTrafficShapingHandler.java | 4 +- .../handler/ssl/CipherSuiteCanaryTest.java | 30 ++-- .../ssl/OpenSslPrivateKeyMethodTest.java | 18 +- .../ssl/ParameterizedSslHandlerTest.java | 8 +- .../io/netty/handler/ssl/SSLEngineTest.java | 9 +- .../handler/ssl/SniClientJava8TestUtil.java | 2 +- .../io/netty/handler/ssl/SniClientTest.java | 2 +- .../io/netty/handler/ssl/SniHandlerTest.java | 4 +- .../io/netty/handler/ssl/SslErrorTest.java | 2 +- .../io/netty/handler/ssl/SslHandlerTest.java | 6 +- .../java/io/netty/resolver/dns/Cache.java | 5 + .../netty/resolver/dns/DnsNameResolver.java | 22 +-- .../netty/resolver/dns/DnsQueryContext.java | 2 +- .../netty/resolver/dns/DnsResolveContext.java | 8 +- .../resolver/dns/InflightNameResolver.java | 17 +- .../dns/DnsAddressResolverGroupTest.java | 2 +- .../resolver/dns/DnsNameResolverTest.java | 2 +- .../resolver/AbstractAddressResolver.java | 24 +-- .../io/netty/resolver/SimpleNameResolver.java | 8 +- .../socket/AbstractSocketReuseFdTest.java | 4 +- .../socket/DatagramConnectNotExistsTest.java | 2 +- .../socket/SocketBufReleaseTest.java | 5 +- .../transport/socket/SocketConnectTest.java | 2 +- .../socket/SocketGatheringWriteTest.java | 2 +- .../socket/SocketStringEchoTest.java | 4 +- .../socket/TrafficShapingHandlerTest.java | 2 +- .../channel/epoll/AbstractEpollChannel.java | 2 +- .../epoll/AbstractEpollStreamChannel.java | 9 +- .../channel/epoll/EpollDatagramChannel.java | 14 +- .../channel/kqueue/AbstractKQueueChannel.java | 2 +- .../kqueue/AbstractKQueueStreamChannel.java | 9 +- .../channel/kqueue/KQueueDatagramChannel.java | 16 +- .../channel/sctp/nio/NioSctpChannel.java | 4 +- .../sctp/nio/NioSctpServerChannel.java | 4 +- .../io/netty/bootstrap/AbstractBootstrap.java | 15 +- .../java/io/netty/bootstrap/Bootstrap.java | 7 +- .../io/netty/bootstrap/ServerBootstrap.java | 5 +- .../AbstractCoalescingBufferQueue.java | 4 +- .../channel/DefaultChannelHandlerContext.java | 22 +-- .../netty/channel/DefaultChannelPipeline.java | 25 ++- .../io/netty/channel/PendingWriteQueue.java | 2 +- .../netty/channel/nio/AbstractNioChannel.java | 12 +- .../socket/nio/NioDatagramChannel.java | 12 +- .../channel/socket/nio/NioSocketChannel.java | 6 +- .../channel/DefaultChannelPipelineTest.java | 31 ++-- .../netty/channel/PendingWriteQueueTest.java | 14 +- .../channel/embedded/EmbeddedChannelTest.java | 4 +- .../netty/channel/local/LocalChannelTest.java | 2 +- 112 files changed, 629 insertions(+), 610 deletions(-) create mode 100644 common/src/main/java/io/netty/util/concurrent/AsynchronousResult.java diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker.java index aa219e2658..18c10647dd 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker.java @@ -268,7 +268,7 @@ public abstract class WebSocketClientHandshaker { promise.setFailure(future.cause()); } }); - return promise; + return promise.asFuture(); } /** @@ -432,7 +432,7 @@ public abstract class WebSocketClientHandshaker { } catch (Throwable cause) { promise.setFailure(cause); } - return promise; + return promise.asFuture(); } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientProtocolHandshakeHandler.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientProtocolHandshakeHandler.java index 6aa4e49258..055cde8b46 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientProtocolHandshakeHandler.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientProtocolHandshakeHandler.java @@ -117,7 +117,7 @@ class WebSocketClientProtocolHandshakeHandler implements ChannelHandler { }, handshakeTimeoutMillis, TimeUnit.MILLISECONDS); // Cancel the handshake timeout when handshake is finished. - localHandshakePromise.addListener(f -> timeoutFuture.cancel(false)); + localHandshakePromise.asFuture().addListener(f -> timeoutFuture.cancel(false)); } /** @@ -126,6 +126,6 @@ class WebSocketClientProtocolHandshakeHandler implements ChannelHandler { * @return current handshake future */ Future getHandshakeFuture() { - return handshakePromise; + return handshakePromise.asFuture(); } } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketProtocolHandler.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketProtocolHandler.java index 54d0bdb593..dab9bdc726 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketProtocolHandler.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketProtocolHandler.java @@ -85,13 +85,14 @@ abstract class WebSocketProtocolHandler extends MessageToMessageDecoder future = closeSent == null ? write(ctx, new CloseWebSocketFrame(closeStatus)) : closeSent; + final Future future = closeSent == null ? + write(ctx, new CloseWebSocketFrame(closeStatus)) : closeSent.asFuture(); flush(ctx); applyCloseSentTimeout(ctx); Promise promise = ctx.newPromise(); future.addListener(f -> ctx.close().cascadeTo(promise)); - return promise; + return promise.asFuture(); } @Override @@ -104,7 +105,7 @@ abstract class WebSocketProtocolHandler extends MessageToMessageDecoder promise = ctx.newPromise(); closeSent(promise); ctx.write(msg).cascadeTo(closeSent); - return promise; + return promise.asFuture(); } return ctx.write(msg); } @@ -124,7 +125,7 @@ abstract class WebSocketProtocolHandler extends MessageToMessageDecoder timeoutTask.cancel(false)); + closeSent.asFuture().addListener(future -> timeoutTask.cancel(false)); } /** diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker.java index 61261610b0..7cac8e8340 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker.java @@ -311,7 +311,7 @@ public abstract class WebSocketServerHandshaker { } catch (Throwable cause) { promise.setFailure(cause); } - return promise; + return promise.asFuture(); } /** diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandshakeHandler.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandshakeHandler.java index 2afa09e8cd..5c35b39784 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandshakeHandler.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerProtocolHandshakeHandler.java @@ -27,7 +27,6 @@ import io.netty.handler.codec.http.HttpResponse; import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler.ServerHandshakeStateEvent; import io.netty.handler.ssl.SslHandler; import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.FutureListener; import io.netty.util.concurrent.Promise; import java.util.Objects; @@ -158,6 +157,6 @@ class WebSocketServerProtocolHandshakeHandler implements ChannelHandler { }, handshakeTimeoutMillis, TimeUnit.MILLISECONDS); // Cancel the handshake timeout when handshake is finished. - localHandshakePromise.addListener(f -> timeoutFuture.cancel(false)); + localHandshakePromise.asFuture().addListener(f -> timeoutFuture.cancel(false)); } } diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/HttpServerUpgradeHandlerTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/HttpServerUpgradeHandlerTest.java index 507e05c8c9..7bc3a329e3 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/HttpServerUpgradeHandlerTest.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/HttpServerUpgradeHandlerTest.java @@ -101,8 +101,8 @@ public class HttpServerUpgradeHandlerTest { writeUpgradeMessage = true; Promise promise = ctx.newPromise(); ctx.channel().executor().execute(() -> ctx.write(msg).cascadeTo(promise)); - promise.addListener(f -> writeFlushed = true); - return promise; + Future future = promise.asFuture(); + return future.addListener(f -> writeFlushed = true); } }; diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketProtocolHandlerTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketProtocolHandlerTest.java index b361ff98d9..b88c460e0a 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketProtocolHandlerTest.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketProtocolHandlerTest.java @@ -158,7 +158,7 @@ public class WebSocketProtocolHandlerTest { EmbeddedChannel channel = new EmbeddedChannel(new ChannelHandler() { @Override public Future write(ChannelHandlerContext ctx, Object msg) { - Future future = ctx.newPromise(); + Future future = ctx.newPromise().asFuture(); ref.set(future); ReferenceCountUtil.release(msg); return future; diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/AbstractHttp2StreamChannel.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/AbstractHttp2StreamChannel.java index 22e3602d33..7b99ab9bb5 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/AbstractHttp2StreamChannel.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/AbstractHttp2StreamChannel.java @@ -334,7 +334,7 @@ abstract class AbstractHttp2StreamChannel extends DefaultAttributeMap implements @Override public Future closeFuture() { - return closePromise; + return closePromise.asFuture(); } @Override @@ -514,7 +514,7 @@ abstract class AbstractHttp2StreamChannel extends DefaultAttributeMap implements promise.setSuccess(null); } else { // This means close() was called before so we just register a listener and return - closePromise.addListener(promise, (p, future) -> p.setSuccess(null)); + closeFuture().addListener(promise, (p, future) -> p.setSuccess(null)); } return; } diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/CompressorHttp2ConnectionEncoder.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/CompressorHttp2ConnectionEncoder.java index 4436bd872b..545a7366f1 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/CompressorHttp2ConnectionEncoder.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/CompressorHttp2ConnectionEncoder.java @@ -187,7 +187,7 @@ public class CompressorHttp2ConnectionEncoder extends DecoratingHttp2ConnectionE buf = nextBuf; } combiner.finish(promise); - return promise; + return promise.asFuture(); } catch (Throwable cause) { return ctx.newFailedFuture(cause); } finally { diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2Connection.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2Connection.java index 82d03cc93c..91e28cf03e 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2Connection.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2Connection.java @@ -123,7 +123,7 @@ public class DefaultHttp2Connection implements Http2Connection { if (closePromise == promise) { // Do nothing } else { - closePromise.addListener(new UnaryPromiseNotifier<>(promise)); + closePromise.asFuture().addListener(new UnaryPromiseNotifier<>(promise)); } } else { closePromise = promise; diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2ConnectionEncoder.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2ConnectionEncoder.java index 63b9d837cc..bdba4f1383 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2ConnectionEncoder.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2ConnectionEncoder.java @@ -143,7 +143,7 @@ public class DefaultHttp2ConnectionEncoder implements Http2ConnectionEncoder, Ht // Hand control of the frame to the flow controller. flowController().addFlowControlled(stream, new FlowControlledData(stream, data, padding, endOfStream, promise, ctx.channel())); - return promise; + return promise.asFuture(); } @Override @@ -266,7 +266,7 @@ public class DefaultHttp2ConnectionEncoder implements Http2ConnectionEncoder, Ht flowController.addFlowControlled(stream, new FlowControlledHeaders(stream, headers, hasPriority, streamDependency, weight, exclusive, padding, true, promise)); - return promise; + return promise.asFuture(); } } catch (Throwable t) { lifecycleManager.onError(ctx, true, t); @@ -479,7 +479,7 @@ public class DefaultHttp2ConnectionEncoder implements Http2ConnectionEncoder, Ht // queue and it is not end of stream yet. Just complete their promises by getting the buffer // corresponding to 0 bytes and writing it to the channel (to preserve notification order). Promise writePromise = ctx.newPromise(); - writePromise.addListener(this); + writePromise.asFuture().addListener(this); ctx.write(queue.remove(0, writePromise)).cascadeTo(writePromise); } return; @@ -493,7 +493,7 @@ public class DefaultHttp2ConnectionEncoder implements Http2ConnectionEncoder, Ht // Determine how much data to write. int writableData = min(queuedData, allowedBytes); Promise writePromise = ctx.newPromise(); - writePromise.addListener(this); + writePromise.asFuture().addListener(this); ByteBuf toWrite = queue.remove(writableData, writePromise); dataSize = queue.readableBytes(); @@ -572,7 +572,7 @@ public class DefaultHttp2ConnectionEncoder implements Http2ConnectionEncoder, Ht boolean isInformational = validateHeadersSentState(stream, headers, connection.isServer(), endOfStream); // The code is currently requiring adding this listener before writing, in order to call onError() before // closeStreamLocal(). - promise.addListener(this); + promise.asFuture().addListener(this); Future f = sendHeaders(frameWriter, ctx, stream.id(), headers, hasPriority, streamDependency, weight, exclusive, padding, endOfStream); @@ -612,7 +612,7 @@ public class DefaultHttp2ConnectionEncoder implements Http2ConnectionEncoder, Ht @Override public void writeComplete() { if (endOfStream) { - lifecycleManager.closeStreamLocal(stream, promise); + lifecycleManager.closeStreamLocal(stream, promise.asFuture()); } } diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2CodecUtil.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2CodecUtil.java index 7f1847f10a..43e5fec1f4 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2CodecUtil.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2CodecUtil.java @@ -23,6 +23,7 @@ import io.netty.handler.ssl.ApplicationProtocolNames; import io.netty.util.AsciiString; import io.netty.util.concurrent.DefaultPromise; import io.netty.util.concurrent.EventExecutor; +import io.netty.util.concurrent.Future; import io.netty.util.concurrent.Promise; import io.netty.util.internal.UnstableApi; @@ -284,13 +285,13 @@ public final class Http2CodecUtil { /** * Signify that no more {@link #newPromise()} allocations will be made. * The aggregation can not be successful until this method is called. - * @return The promise that is the aggregation of all promises allocated with {@link #newPromise()}. + * @return The {@link Future} that is the aggregation of all promises allocated with {@link #newPromise()}. */ - public Promise doneAllocatingPromises() { + public Future doneAllocatingPromises() { if (!doneAllocating) { doneAllocating = true; if (doneCount == expectedCount || expectedCount == 0) { - return setPromise(); + return setPromise().asFuture(); } } return this; @@ -323,7 +324,7 @@ public final class Http2CodecUtil { ++doneCount; setAggregateFailure(cause); if (allPromisesDone()) { - return setPromise(); + setPromise(); } } return this; @@ -369,11 +370,12 @@ public final class Http2CodecUtil { private Promise setPromise() { if (aggregateFailure == null) { promise.setSuccess(null); - return super.setSuccess(null); + super.setSuccess(null); } else { promise.setFailure(aggregateFailure); - return super.setFailure(aggregateFailure); + super.setFailure(aggregateFailure); } + return this; } private boolean tryPromise() { diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2ConnectionHandler.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2ConnectionHandler.java index 0411a8e24c..cde8ff15b0 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2ConnectionHandler.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2ConnectionHandler.java @@ -454,7 +454,7 @@ public class Http2ConnectionHandler extends ByteToMessageDecoder implements Http ctx.flush(); Promise promise = ctx.newPromise(); doGracefulShutdown(ctx, f, promise); - return promise; + return promise.asFuture(); } private FutureListener newClosingChannelFutureListener( diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2StreamChannelBootstrap.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2StreamChannelBootstrap.java index a27b660960..f59146ac61 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2StreamChannelBootstrap.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2StreamChannelBootstrap.java @@ -128,7 +128,7 @@ public final class Http2StreamChannelBootstrap { } catch (Throwable cause) { promise.setFailure(cause); } - return promise; + return promise.asFuture(); } @SuppressWarnings("deprecation") @@ -189,7 +189,7 @@ public final class Http2StreamChannelBootstrap { if (future1.isSuccess()) { promise.setSuccess(streamChannel); } else if (future1.isCancelled()) { - promise.cancel(false); + promise.cancel(); } else { if (streamChannel.isRegistered()) { streamChannel.close(); diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/HttpToHttp2ConnectionHandler.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/HttpToHttp2ConnectionHandler.java index 002d57580a..4ffa0389ac 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/HttpToHttp2ConnectionHandler.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/HttpToHttp2ConnectionHandler.java @@ -144,7 +144,7 @@ public class HttpToHttp2ConnectionHandler extends Http2ConnectionHandler { } promiseAggregator.doneAllocatingPromises(); } - return promise; + return promise.asFuture(); } private static Future writeHeaders(ChannelHandlerContext ctx, Http2ConnectionEncoder encoder, int streamId, diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/StreamBufferingEncoder.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/StreamBufferingEncoder.java index 689d54aa5b..43feb27a75 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/StreamBufferingEncoder.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/StreamBufferingEncoder.java @@ -182,7 +182,7 @@ public class StreamBufferingEncoder extends DecoratingHttp2ConnectionEncoder { pendingStream.frames.add(new HeadersFrame(headers, streamDependency, weight, exclusive, padding, endOfStream, promise)); - return promise; + return promise.asFuture(); } @Override @@ -215,7 +215,7 @@ public class StreamBufferingEncoder extends DecoratingHttp2ConnectionEncoder { if (pendingStream != null) { Promise promise = ctx.newPromise(); pendingStream.frames.add(new DataFrame(data, padding, endOfStream, promise)); - return promise; + return promise.asFuture(); } else { ReferenceCountUtil.safeRelease(data); return ctx.newFailedFuture(connectionError(PROTOCOL_ERROR, "Stream does not exist %d", streamId)); diff --git a/codec-http2/src/test/java/io/netty/handler/codec/http2/DefaultHttp2ConnectionTest.java b/codec-http2/src/test/java/io/netty/handler/codec/http2/DefaultHttp2ConnectionTest.java index 126a2e9faf..e40bdf7f71 100644 --- a/codec-http2/src/test/java/io/netty/handler/codec/http2/DefaultHttp2ConnectionTest.java +++ b/codec-http2/src/test/java/io/netty/handler/codec/http2/DefaultHttp2ConnectionTest.java @@ -155,9 +155,10 @@ public class DefaultHttp2ConnectionTest { final Promise promise = group.next().newPromise(); final CountDownLatch latch = new CountDownLatch(client.numActiveStreams()); client.forEachActiveStream(stream -> { - client.close(promise.addListener(future -> { + promise.asFuture().addListener(future -> { latch.countDown(); - })); + }); + client.close(promise); return true; }); assertTrue(latch.await(5, TimeUnit.SECONDS)); @@ -183,9 +184,10 @@ public class DefaultHttp2ConnectionTest { return true; }); } catch (Http2Exception ignored) { - client.close(promise.addListener(future -> { + promise.asFuture().addListener(future -> { latch.countDown(); - })); + }); + client.close(promise); } assertTrue(latch.await(5, TimeUnit.SECONDS)); } @@ -632,9 +634,10 @@ public class DefaultHttp2ConnectionTest { private void testRemoveAllStreams() throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); final Promise promise = group.next().newPromise(); - client.close(promise.addListener(future -> { + promise.asFuture().addListener(future -> { latch.countDown(); - })); + }); + client.close(promise); assertTrue(latch.await(5, TimeUnit.SECONDS)); } diff --git a/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2ConnectionHandlerTest.java b/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2ConnectionHandlerTest.java index 26885a8db2..a11493e2bb 100644 --- a/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2ConnectionHandlerTest.java +++ b/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2ConnectionHandlerTest.java @@ -54,8 +54,8 @@ import static io.netty.handler.codec.http2.Http2Stream.State.CLOSED; import static io.netty.handler.codec.http2.Http2Stream.State.IDLE; import static io.netty.util.CharsetUtil.US_ASCII; import static io.netty.util.CharsetUtil.UTF_8; +import static io.netty.util.concurrent.DefaultPromise.newSuccessfulPromise; import static java.util.concurrent.TimeUnit.SECONDS; -import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertSame; @@ -194,7 +194,7 @@ public class Http2ConnectionHandlerTest { when(ctx.newFailedFuture(any(Throwable.class))) .thenAnswer(invocationOnMock -> DefaultPromise.newFailedPromise(executor, invocationOnMock.getArgument(0))); - when(ctx.newSucceededFuture()).thenReturn(DefaultPromise.newSuccessfulPromise(executor, null)); + when(ctx.newSucceededFuture()).thenReturn(newSuccessfulPromise(executor, (Void) null).asFuture()); when(ctx.newPromise()).thenReturn(promise); when(ctx.write(any())).thenReturn(future); when(ctx.executor()).thenReturn(executor); @@ -204,9 +204,9 @@ public class Http2ConnectionHandlerTest { return null; }).when(ctx).fireChannelRead(any()); doAnswer((Answer>) in -> - DefaultPromise.newSuccessfulPromise(executor, null)).when(ctx).write(any()); + newSuccessfulPromise(executor, (Void) null).asFuture()).when(ctx).write(any()); doAnswer((Answer>) in -> - DefaultPromise.newSuccessfulPromise(executor, null)).when(ctx).close(); + newSuccessfulPromise(executor, (Void) null).asFuture()).when(ctx).close(); } private Http2ConnectionHandler newHandler() throws Exception { diff --git a/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2ConnectionRoundtripTest.java b/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2ConnectionRoundtripTest.java index 5b33a9e3dd..9f405c427c 100644 --- a/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2ConnectionRoundtripTest.java +++ b/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2ConnectionRoundtripTest.java @@ -150,8 +150,8 @@ public class Http2ConnectionRoundtripTest { doAnswer(invocationOnMock -> { ChannelHandlerContext ctx = invocationOnMock.getArgument(0); http2Server.encoder().writeHeaders(ctx, - (Integer) invocationOnMock.getArgument(1), - (Http2Headers) invocationOnMock.getArgument(2), + invocationOnMock.getArgument(1), + invocationOnMock.getArgument(2), 0, false); http2Server.flush(ctx); @@ -615,7 +615,7 @@ public class Http2ConnectionRoundtripTest { ExecutionException e = assertThrows(ExecutionException.class, new Executable() { @Override public void execute() throws Throwable { - promise.get(); + promise.asFuture().get(); } }); assertThat(e.getCause(), is(instanceOf(IllegalReferenceCountException.class))); @@ -668,11 +668,11 @@ public class Http2ConnectionRoundtripTest { ExecutionException e = assertThrows(ExecutionException.class, new Executable() { @Override public void execute() throws Throwable { - dataPromise.get(); + dataPromise.asFuture().get(); } }); assertThat(e.getCause(), is(instanceOf(IllegalStateException.class))); - assertPromise.sync(); + assertPromise.asFuture().sync(); } @Test @@ -1094,10 +1094,6 @@ public class Http2ConnectionRoundtripTest { return ctx().newPromise(); } - private Promise serverNewPromise() { - return serverCtx().newPromise(); - } - private static Http2Headers dummyHeaders() { return new DefaultHttp2Headers(false).method(new AsciiString("GET")).scheme(new AsciiString("https")) .authority(new AsciiString("example.org")).path(new AsciiString("/some/path/resource2")) diff --git a/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2ControlFrameLimitEncoderTest.java b/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2ControlFrameLimitEncoderTest.java index 256f22c2e4..ad4892b944 100644 --- a/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2ControlFrameLimitEncoderTest.java +++ b/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2ControlFrameLimitEncoderTest.java @@ -100,23 +100,23 @@ public class Http2ControlFrameLimitEncoderTest { when(frameSizePolicy.maxFrameSize()).thenReturn(DEFAULT_MAX_FRAME_SIZE); when(writer.writeRstStream(eq(ctx), anyInt(), anyLong())) - .thenAnswer((Answer>) invocationOnMock -> handlePromise()); + .thenAnswer((Answer>) invocationOnMock -> handlePromise().asFuture()); when(writer.writeSettingsAck(any(ChannelHandlerContext.class))) - .thenAnswer((Answer>) invocationOnMock -> handlePromise()); + .thenAnswer((Answer>) invocationOnMock -> handlePromise().asFuture()); when(writer.writePing(any(ChannelHandlerContext.class), anyBoolean(), anyLong())) .thenAnswer((Answer>) invocationOnMock -> { Promise promise = handlePromise(); if (invocationOnMock.getArgument(1) == Boolean.FALSE) { promise.trySuccess(null); } - return promise; + return promise.asFuture(); }); when(writer.writeGoAway(any(ChannelHandlerContext.class), anyInt(), anyLong(), any(ByteBuf.class))) .thenAnswer((Answer>) invocationOnMock -> { ReferenceCountUtil.release(invocationOnMock.getArgument(3)); Promise promise = ImmediateEventExecutor.INSTANCE.newPromise(); goAwayPromises.offer(promise); - return promise; + return promise.asFuture(); }); Http2Connection connection = new DefaultHttp2Connection(false); connection.remote().flowController(new DefaultHttp2RemoteFlowController(connection)); @@ -136,8 +136,8 @@ public class Http2ControlFrameLimitEncoderTest { when(ctx.alloc()).thenReturn(UnpooledByteBufAllocator.DEFAULT); when(channel.alloc()).thenReturn(UnpooledByteBufAllocator.DEFAULT); when(executor.inEventLoop()).thenReturn(true); - doAnswer((Answer) invocation -> newPromise()).when(ctx).newPromise(); - doAnswer((Answer) invocation -> + doAnswer((Answer>) invocation -> newPromise()).when(ctx).newPromise(); + doAnswer((Answer>) invocation -> ImmediateEventExecutor.INSTANCE.newFailedFuture(invocation.getArgument(0))) .when(ctx).newFailedFuture(any(Throwable.class)); @@ -164,7 +164,7 @@ public class Http2ControlFrameLimitEncoderTest { } @AfterEach - public void teardown() { + public void tearDown() { // Close and release any buffered frames. encoder.close(); diff --git a/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2FrameCodecTest.java b/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2FrameCodecTest.java index ab996a09aa..78db1a0ca6 100644 --- a/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2FrameCodecTest.java +++ b/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2FrameCodecTest.java @@ -626,7 +626,7 @@ public class Http2FrameCodecTest { Future f = channel.writeAndFlush(new DefaultHttp2DataFrame(data).stream(stream)); assertTrue(f.isSuccess()); - listenerExecuted.syncUninterruptibly(); + listenerExecuted.asFuture().syncUninterruptibly(); assertTrue(listenerExecuted.isSuccess()); } diff --git a/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2FrameRoundtripTest.java b/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2FrameRoundtripTest.java index dd1d24fad1..c0f7adba59 100644 --- a/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2FrameRoundtripTest.java +++ b/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2FrameRoundtripTest.java @@ -99,7 +99,7 @@ public class Http2FrameRoundtripTest { when(ctx.executor()).thenReturn(executor); when(ctx.channel()).thenReturn(channel); doAnswer((Answer>) in -> - DefaultPromise.newSuccessfulPromise(executor, null)).when(ctx).write(any()); + DefaultPromise.newSuccessfulPromise(executor, (Void) null).asFuture()).when(ctx).write(any()); doAnswer((Answer) in -> Unpooled.buffer()).when(alloc).buffer(); doAnswer((Answer) in -> Unpooled.buffer((Integer) in.getArguments()[0])).when(alloc).buffer(anyInt()); doAnswer((Answer>) invocation -> @@ -110,7 +110,7 @@ public class Http2FrameRoundtripTest { } @AfterEach - public void teardown() { + public void tearDown() { try { // Release all of the buffers. for (ByteBuf buf : needReleasing) { diff --git a/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2MultiplexTest.java b/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2MultiplexTest.java index 0a5c1bfee7..9085b4ba19 100644 --- a/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2MultiplexTest.java +++ b/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2MultiplexTest.java @@ -72,7 +72,6 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -@SuppressWarnings("unchecked") public abstract class Http2MultiplexTest { private final Http2Headers request = new DefaultHttp2Headers() .method(HttpMethod.GET.asciiName()).scheme(HttpScheme.HTTPS.name()) @@ -729,7 +728,7 @@ public abstract class Http2MultiplexTest { // Create a promise before actually doing the close, because otherwise we would be adding a listener to a future // that is already completed because we are using EmbeddedChannel which executes code in the JUnit thread. Promise p = childChannel.newPromise(); - p.addListener(childChannel, (channel, future) -> { + p.asFuture().addListener(childChannel, (channel, future) -> { channelOpen.set(channel.isOpen()); channelActive.set(channel.isActive()); }); @@ -972,7 +971,7 @@ public abstract class Http2MultiplexTest { Promise promise = childChannel.newPromise(); childChannel.unsafe().close(promise); - promise.syncUninterruptibly(); + promise.asFuture().syncUninterruptibly(); childChannel.closeFuture().syncUninterruptibly(); } diff --git a/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2StreamChannelBootstrapTest.java b/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2StreamChannelBootstrapTest.java index 0ba2ba6acb..94756e88ad 100644 --- a/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2StreamChannelBootstrapTest.java +++ b/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2StreamChannelBootstrapTest.java @@ -101,10 +101,10 @@ public class Http2StreamChannelBootstrapTest { ExecutionException exception = assertThrows(ExecutionException.class, new Executable() { @Override public void execute() throws Throwable { - promise.get(3, SECONDS); + promise.asFuture().get(3, SECONDS); } }); - assertThat(exception.getCause(), IsInstanceOf.instanceOf(ClosedChannelException.class)); + assertThat(exception.getCause(), IsInstanceOf.instanceOf(ClosedChannelException.class)); } finally { safeClose(clientChannel); safeClose(serverConnectedChannel); diff --git a/codec-http2/src/test/java/io/netty/handler/codec/http2/StreamBufferingEncoderTest.java b/codec-http2/src/test/java/io/netty/handler/codec/http2/StreamBufferingEncoderTest.java index 9c1897761b..46439be6ca 100644 --- a/codec-http2/src/test/java/io/netty/handler/codec/http2/StreamBufferingEncoderTest.java +++ b/codec-http2/src/test/java/io/netty/handler/codec/http2/StreamBufferingEncoderTest.java @@ -25,7 +25,6 @@ import io.netty.channel.ChannelMetadata; import io.netty.channel.DefaultMessageSizeEstimator; import io.netty.handler.codec.http2.StreamBufferingEncoder.Http2GoAwayException; import io.netty.util.ReferenceCountUtil; -import io.netty.util.concurrent.DefaultPromise; import io.netty.util.concurrent.EventExecutor; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.ImmediateEventExecutor; @@ -545,9 +544,7 @@ public class StreamBufferingEncoderTest { ReferenceCountUtil.safeRelease(a); } - Promise future = newPromise(); - future.setSuccess(null); - return future; + return ImmediateEventExecutor.INSTANCE.newSucceededFuture(null); }; } @@ -557,16 +554,16 @@ public class StreamBufferingEncoderTest { public Future answer(InvocationOnMock invocation) throws Throwable { for (Object a : invocation.getArguments()) { if (a instanceof Promise) { - return (Future) a; + return ((Promise) a).asFuture(); } } - return newPromise(); + return newPromise().asFuture(); } }; } private static Promise newPromise() { - return new DefaultPromise(ImmediateEventExecutor.INSTANCE); + return ImmediateEventExecutor.INSTANCE.newPromise(); } private static ByteBuf data() { diff --git a/codec/src/main/java/io/netty/handler/codec/MessageToMessageEncoder.java b/codec/src/main/java/io/netty/handler/codec/MessageToMessageEncoder.java index b825b831c2..ded2114c8d 100644 --- a/codec/src/main/java/io/netty/handler/codec/MessageToMessageEncoder.java +++ b/codec/src/main/java/io/netty/handler/codec/MessageToMessageEncoder.java @@ -106,7 +106,7 @@ public abstract class MessageToMessageEncoder extends ChannelHandlerAdapter { writePromiseCombiner(ctx, out, promise); } } - return promise; + return promise.asFuture(); } else { return ctx.write(msg); } diff --git a/codec/src/main/java/io/netty/handler/codec/compression/Bzip2Encoder.java b/codec/src/main/java/io/netty/handler/codec/compression/Bzip2Encoder.java index c3d0ec47c2..6523436d85 100644 --- a/codec/src/main/java/io/netty/handler/codec/compression/Bzip2Encoder.java +++ b/codec/src/main/java/io/netty/handler/codec/compression/Bzip2Encoder.java @@ -183,7 +183,7 @@ public class Bzip2Encoder extends MessageToByteEncoder { Future f = finishEncode(ctx()); f.cascadeTo(promise); }); - return promise; + return promise.asFuture(); } } @@ -198,7 +198,7 @@ public class Bzip2Encoder extends MessageToByteEncoder { // Ensure the channel is closed even if the write operation completes in time. ctx.executor().schedule(() -> ctx.close().cascadeTo(promise), 10, TimeUnit.SECONDS); // FIXME: Magic number - return promise; + return promise.asFuture(); } private Future finishEncode(final ChannelHandlerContext ctx) { diff --git a/codec/src/main/java/io/netty/handler/codec/compression/JdkZlibEncoder.java b/codec/src/main/java/io/netty/handler/codec/compression/JdkZlibEncoder.java index 168a024bd7..eee877b127 100644 --- a/codec/src/main/java/io/netty/handler/codec/compression/JdkZlibEncoder.java +++ b/codec/src/main/java/io/netty/handler/codec/compression/JdkZlibEncoder.java @@ -165,7 +165,7 @@ public class JdkZlibEncoder extends ZlibEncoder { Future f = finishEncode(ctx()); f.cascadeTo(p); }); - return p; + return p.asFuture(); } } @@ -265,7 +265,7 @@ public class JdkZlibEncoder extends ZlibEncoder { // Ensure the channel is closed even if the write operation completes in time. ctx.executor().schedule(() -> ctx.close().cascadeTo(promise), 10, TimeUnit.SECONDS); // FIXME: Magic number - return promise; + return promise.asFuture(); } private Future finishEncode(final ChannelHandlerContext ctx) { diff --git a/codec/src/main/java/io/netty/handler/codec/compression/Lz4FrameEncoder.java b/codec/src/main/java/io/netty/handler/codec/compression/Lz4FrameEncoder.java index adc1741912..5b63aeee78 100644 --- a/codec/src/main/java/io/netty/handler/codec/compression/Lz4FrameEncoder.java +++ b/codec/src/main/java/io/netty/handler/codec/compression/Lz4FrameEncoder.java @@ -349,7 +349,7 @@ public class Lz4FrameEncoder extends MessageToByteEncoder { Future f = finishEncode(ctx()); f.cascadeTo(promise); }); - return promise; + return promise.asFuture(); } } @@ -364,7 +364,7 @@ public class Lz4FrameEncoder extends MessageToByteEncoder { // Ensure the channel is closed even if the write operation completes in time. ctx.executor().schedule(() -> ctx.close().cascadeTo(promise), 10, TimeUnit.SECONDS); // FIXME: Magic number - return promise; + return promise.asFuture(); } private ChannelHandlerContext ctx() { diff --git a/common/src/main/java/io/netty/util/concurrent/AbstractEventExecutor.java b/common/src/main/java/io/netty/util/concurrent/AbstractEventExecutor.java index 259b0c8f4e..b08d7d5943 100644 --- a/common/src/main/java/io/netty/util/concurrent/AbstractEventExecutor.java +++ b/common/src/main/java/io/netty/util/concurrent/AbstractEventExecutor.java @@ -36,7 +36,7 @@ public abstract class AbstractEventExecutor extends AbstractExecutorService impl static final long DEFAULT_SHUTDOWN_TIMEOUT = 15; private final Collection selfCollection = Collections.singleton(this); - private final Future successfulVoidFuture = DefaultPromise.newSuccessfulPromise(this, null); + private final Future successfulVoidFuture = DefaultPromise.newSuccessfulPromise(this, null).asFuture(); @Override public EventExecutor next() { @@ -87,12 +87,13 @@ public abstract class AbstractEventExecutor extends AbstractExecutorService impl Future f = (Future) successfulVoidFuture; return f; } - return DefaultPromise.newSuccessfulPromise(this, result); + return DefaultPromise.newSuccessfulPromise(this, result).asFuture(); } @Override public Future newFailedFuture(Throwable cause) { - return DefaultPromise.newFailedPromise(this, cause); + Promise promise = DefaultPromise.newFailedPromise(this, cause); + return promise.asFuture(); } @Override diff --git a/common/src/main/java/io/netty/util/concurrent/AbstractScheduledEventExecutor.java b/common/src/main/java/io/netty/util/concurrent/AbstractScheduledEventExecutor.java index 778db2f28d..478d479cb1 100644 --- a/common/src/main/java/io/netty/util/concurrent/AbstractScheduledEventExecutor.java +++ b/common/src/main/java/io/netty/util/concurrent/AbstractScheduledEventExecutor.java @@ -393,6 +393,11 @@ public abstract class AbstractScheduledEventExecutor extends AbstractEventExecut return this; } + @Override + public boolean cancel() { + return cancel(false); + } + @Override public boolean isSuccess() { return future.isSuccess(); diff --git a/common/src/main/java/io/netty/util/concurrent/AsynchronousResult.java b/common/src/main/java/io/netty/util/concurrent/AsynchronousResult.java new file mode 100644 index 0000000000..968585aa91 --- /dev/null +++ b/common/src/main/java/io/netty/util/concurrent/AsynchronousResult.java @@ -0,0 +1,96 @@ +/* + * Copyright 2021 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.netty.util.concurrent; + +import java.util.concurrent.CancellationException; + +/** + * A result of an asynchronous operation. + *

+ * This interface is used as the super-interface of {@link Promise} and {@link Future}, and these should generally be + * used instead. + */ +interface AsynchronousResult { + /** + * Cancel this asynchronous operation, unless it has already been completed. + *

+ * A cancelled operation is considered to be {@linkplain #isFailed() failed}. + *

+ * If the cancellation was successful, the result of this operation will be that it has failed with a + * {@link CancellationException}. + *

+ * Cancellation will not cause any threads working on the operation to be {@linkplain Thread#interrupt() + * interrupted}. + * + * @return {@code true} if the operation was cancelled by this call, otherwise {@code false}. + */ + boolean cancel(); + + /** + * Returns {@code true} if and only if the operation was completed successfully. + */ + boolean isSuccess(); + + /** + * Returns {@code true} if and only if the operation was completed and failed. + */ + boolean isFailed(); + + /** + * Return {@code true} if this operation has been {@linkplain #cancel() cancelled}. + * + * @return {@code true} if this operation has been cancelled, otherwise {@code false}. + */ + boolean isCancelled(); + + /** + * Return {@code true} if this operation has been completed either {@linkplain Promise#setSuccess(Object) + * successfully}, {@linkplain Promise#setFailure(Throwable) unsuccessfully}, or through + * {@linkplain #cancel() cancellation}. + * + * @return {@code true} if this operation has completed, otherwise {@code false}. + */ + boolean isDone(); + + /** + * returns {@code true} if and only if the operation can be cancelled via {@link #cancel()}. + */ + boolean isCancellable(); + + /** + * Return the successful result of this asynchronous operation, if any. + * If the operation has not yet been completed, then this will throw {@link IllegalStateException}. + * If the operation has been cancelled or failed with an exception, then this returns {@code null}. + * Note that asynchronous operations can also be completed successfully with a {@code null} result. + * + * @return the result of this operation, if completed successfully. + * @throws IllegalStateException if this {@code Future} or {@link Promise} has not completed yet. + */ + V getNow(); + + /** + * Returns the cause of the failed operation if the operation has failed. + * + * @return The cause of the failure, if any. Otherwise {@code null} if succeeded. + * @throws IllegalStateException if this {@code Promise} has not completed yet. + */ + Throwable cause(); + + /** + * Returns the {@link EventExecutor} that is tied to this {@link Promise} or {@link Future}. + */ + EventExecutor executor(); +} diff --git a/common/src/main/java/io/netty/util/concurrent/DefaultFutureCompletionStage.java b/common/src/main/java/io/netty/util/concurrent/DefaultFutureCompletionStage.java index 9043b36c83..62b2b013ce 100644 --- a/common/src/main/java/io/netty/util/concurrent/DefaultFutureCompletionStage.java +++ b/common/src/main/java/io/netty/util/concurrent/DefaultFutureCompletionStage.java @@ -201,7 +201,7 @@ final class DefaultFutureCompletionStage implements FutureCompletionStage promise.setFailure(cause); } }); - return promise.asStage(); + return promise.asFuture().asStage(); } private static void thenApplyAsync0(Promise promise, V value, Function fn) { @@ -234,7 +234,7 @@ final class DefaultFutureCompletionStage implements FutureCompletionStage promise.setFailure(cause); } }); - return promise.asStage(); + return promise.asFuture().asStage(); } private static void thenAcceptAsync0(Promise promise, V value, Consumer action) { @@ -299,7 +299,7 @@ final class DefaultFutureCompletionStage implements FutureCompletionStage applyAndNotify(promise, value2, value1, fn); } }, otherExecutor(executor)); - return promise.asStage(); + return promise.asFuture().asStage(); } private Executor otherExecutor(Executor executor) { @@ -342,7 +342,7 @@ final class DefaultFutureCompletionStage implements FutureCompletionStage }; whenCompleteAsync(consumer, executor); other.whenCompleteAsync(consumer, otherExecutor(executor)); - return promise.asStage(); + return promise.asFuture().asStage(); } @Override @@ -363,7 +363,7 @@ final class DefaultFutureCompletionStage implements FutureCompletionStage }; whenCompleteAsync(consumer, executor); other.whenCompleteAsync(consumer, otherExecutor(executor)); - return promise.asStage(); + return promise.asFuture().asStage(); } @Override @@ -384,7 +384,7 @@ final class DefaultFutureCompletionStage implements FutureCompletionStage }; whenCompleteAsync(consumer, executor); other.whenCompleteAsync(consumer, otherExecutor(executor)); - return promise.asStage(); + return promise.asFuture().asStage(); } @Override @@ -407,7 +407,7 @@ final class DefaultFutureCompletionStage implements FutureCompletionStage promise.setFailure(cause); } }); - return promise.asStage(); + return promise.asFuture().asStage(); } private static void thenComposeAsync0( @@ -449,7 +449,7 @@ final class DefaultFutureCompletionStage implements FutureCompletionStage promise.setSuccess(result); } }); - return promise.asStage(); + return promise.asFuture().asStage(); } @Override @@ -466,7 +466,7 @@ final class DefaultFutureCompletionStage implements FutureCompletionStage safeExecute(executor, () -> whenCompleteAsync0(promise, f, action), promise); } }); - return promise.asStage(); + return promise.asFuture().asStage(); } private static void whenCompleteAsync0( @@ -501,7 +501,7 @@ final class DefaultFutureCompletionStage implements FutureCompletionStage safeExecute(executor, () -> handleAsync0(promise, f, fn), promise); } }); - return promise.asStage(); + return promise.asFuture().asStage(); } @SuppressWarnings("unchecked") 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 2203929756..c72417c0d0 100644 --- a/common/src/main/java/io/netty/util/concurrent/DefaultPromise.java +++ b/common/src/main/java/io/netty/util/concurrent/DefaultPromise.java @@ -30,7 +30,7 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; import static java.util.Objects.requireNonNull; import static java.util.concurrent.TimeUnit.MILLISECONDS; -public class DefaultPromise implements Promise { +public class DefaultPromise implements Promise, Future { private static final InternalLogger logger = InternalLoggerFactory.getInstance(DefaultPromise.class); private static final InternalLogger rejectedExecutionLogger = InternalLoggerFactory.getInstance(DefaultPromise.class.getName() + ".rejectedExecution"); @@ -157,6 +157,11 @@ public class DefaultPromise implements Promise { return !isDone0(result) || !isCancelled0(result); } + @Override + public Future asFuture() { + return this; + } + @Override public boolean isSuccess() { Object result = this.result; @@ -212,7 +217,7 @@ public class DefaultPromise implements Promise { } @Override - public Promise addListener(FutureListener listener) { + public Future addListener(FutureListener listener) { requireNonNull(listener, "listener"); addListener0(listener, null); @@ -224,7 +229,7 @@ public class DefaultPromise implements Promise { } @Override - public Promise addListener(C context, FutureContextListener listener) { + public Future addListener(C context, FutureContextListener listener) { requireNonNull(listener, "listener"); addListener0(listener, context == null ? NULL_CONTEXT : context); @@ -377,6 +382,11 @@ public class DefaultPromise implements Promise { throw new ExecutionException(cause); } + @Override + public boolean cancel() { + return cancel(false); + } + /** * @param mayInterruptIfRunning this value has no effect in this implementation. */ diff --git a/common/src/main/java/io/netty/util/concurrent/Future.java b/common/src/main/java/io/netty/util/concurrent/Future.java index 7f6a8ca730..7f946fbc7e 100644 --- a/common/src/main/java/io/netty/util/concurrent/Future.java +++ b/common/src/main/java/io/netty/util/concurrent/Future.java @@ -151,30 +151,7 @@ import java.util.function.Function; * */ @SuppressWarnings("ClassNameSameAsAncestorName") -public interface Future extends java.util.concurrent.Future { - /** - * Returns {@code true} if and only if the operation was completed successfully. - */ - boolean isSuccess(); - - /** - * Returns {@code true} if and only if the operation was completed and failed. - */ - boolean isFailed(); - - /** - * returns {@code true} if and only if the operation can be cancelled via {@link #cancel(boolean)}. - */ - boolean isCancellable(); - - /** - * Returns the cause of the failed I/O operation if the I/O operation has failed. - * - * @return the cause of the failure. {@code null} if succeeded. - * @throws IllegalStateException if this {@code Future} has not completed yet. - */ - Throwable cause(); - +public interface Future extends java.util.concurrent.Future, AsynchronousResult { /** * Adds the specified listener to this future. The specified listener is notified when this future is {@linkplain * #isDone() done}. If this future is already completed, the specified listener is notified immediately. @@ -258,14 +235,6 @@ public interface Future extends java.util.concurrent.Future { */ boolean awaitUninterruptibly(long timeoutMillis); - /** - * Return the result without blocking. If the future is not done yet this will throw {@link IllegalStateException}. - *

- * - * @throws IllegalStateException if this {@code Future} has not completed yet. - */ - V getNow(); - /** * {@inheritDoc} *

@@ -274,11 +243,6 @@ public interface Future extends java.util.concurrent.Future { @Override boolean cancel(boolean mayInterruptIfRunning); - /** - * Returns the {@link EventExecutor} that is tied to this {@link Future}. - */ - EventExecutor executor(); - @Override default V get() throws InterruptedException, ExecutionException { await(); diff --git a/common/src/main/java/io/netty/util/concurrent/FutureCompletionStage.java b/common/src/main/java/io/netty/util/concurrent/FutureCompletionStage.java index 1bb3a544c2..8301f96361 100644 --- a/common/src/main/java/io/netty/util/concurrent/FutureCompletionStage.java +++ b/common/src/main/java/io/netty/util/concurrent/FutureCompletionStage.java @@ -28,7 +28,7 @@ import java.util.function.Function; /** * A {@link CompletionStage} that provides the same threading semantics and guarantees as the underlying - * {@link io.netty.util.concurrent.Future}, which means that all the callbacks will be executed by {@link #executor()} + * {@link Future}, which means that all the callbacks will be executed by {@link #executor()} * if not specified otherwise (by calling the corresponding *Async methods). * * Please be aware that {@link FutureCompletionStage#toCompletableFuture()} is not supported and so will throw @@ -188,7 +188,7 @@ public interface FutureCompletionStage extends CompletionStage { static FutureCompletionStage toFutureCompletionStage(CompletionStage stage, EventExecutor executor) { Objects.requireNonNull(stage, "stage"); Objects.requireNonNull(executor, "executor"); - if (stage instanceof FutureCompletionStage && ((FutureCompletionStage) stage).executor() == executor) { + if (stage instanceof FutureCompletionStage && ((FutureCompletionStage) stage).executor() == executor) { return (FutureCompletionStage) stage; } @@ -208,6 +208,6 @@ public interface FutureCompletionStage extends CompletionStage { promise.setSuccess(v); } }); - return promise.asStage(); + return promise.asFuture().asStage(); } } diff --git a/common/src/main/java/io/netty/util/concurrent/Futures.java b/common/src/main/java/io/netty/util/concurrent/Futures.java index 609916c619..f9eeb001c2 100644 --- a/common/src/main/java/io/netty/util/concurrent/Futures.java +++ b/common/src/main/java/io/netty/util/concurrent/Futures.java @@ -63,8 +63,9 @@ final class Futures { } Promise promise = future.executor().newPromise(); future.addListener(new Mapper<>(promise, mapper)); - promise.addListener(future, propagateCancel()); - return promise; + Future mappedFuture = promise.asFuture(); + mappedFuture.addListener(future, propagateCancel()); + return mappedFuture; } /** @@ -98,12 +99,13 @@ final class Futures { requireNonNull(mapper, "mapper"); Promise promise = future.executor().newPromise(); future.addListener(new FlatMapper<>(promise, mapper)); + Future mappedFuture = promise.asFuture(); if (!future.isSuccess()) { // Propagate cancellation if future is either incomplete or failed. // Failed means it could be cancelled, so that needs to be propagated. - promise.addListener(future, propagateCancel()); + mappedFuture.addListener(future, propagateCancel()); } - return promise; + return mappedFuture; } @SuppressWarnings("unchecked") @@ -120,7 +122,7 @@ final class Futures { if (completed.isCancelled()) { // Don't check or log if cancellation propagation fails. // Propagation goes both ways, which means at least one future will already be cancelled here. - recipient.cancel(false); + recipient.cancel(); } else { Throwable cause = completed.cause(); recipient.tryFailure(cause); @@ -219,7 +221,7 @@ final class Futures { propagateUncommonCompletion(future, recipient); } else { future.addListener(recipient, passThrough()); - recipient.addListener(future, propagateCancel()); + recipient.asFuture().addListener(future, propagateCancel()); } } catch (Throwable e) { tryFailure(recipient, e, logger); @@ -246,7 +248,7 @@ final class Futures { if (!future.isSuccess()) { // Propagate cancellation if future is either incomplete or failed. // Failed means it could be cancelled, so that needs to be propagated. - promise.addListener(future, propagateCancel()); + promise.asFuture().addListener(future, propagateCancel()); } future.addListener(promise, passThrough()); } diff --git a/common/src/main/java/io/netty/util/concurrent/GlobalEventExecutor.java b/common/src/main/java/io/netty/util/concurrent/GlobalEventExecutor.java index 563e5f6798..bc1bd54e78 100644 --- a/common/src/main/java/io/netty/util/concurrent/GlobalEventExecutor.java +++ b/common/src/main/java/io/netty/util/concurrent/GlobalEventExecutor.java @@ -68,7 +68,7 @@ public final class GlobalEventExecutor extends AbstractScheduledEventExecutor im volatile Thread thread; private final Future terminationFuture = DefaultPromise.newFailedPromise( - this, new UnsupportedOperationException()); + this, new UnsupportedOperationException()).asFuture(); private GlobalEventExecutor() { threadFactory = ThreadExecutorMap.apply(new DefaultThreadFactory( diff --git a/common/src/main/java/io/netty/util/concurrent/ImmediateEventExecutor.java b/common/src/main/java/io/netty/util/concurrent/ImmediateEventExecutor.java index 9076641f28..d2c945320f 100644 --- a/common/src/main/java/io/netty/util/concurrent/ImmediateEventExecutor.java +++ b/common/src/main/java/io/netty/util/concurrent/ImmediateEventExecutor.java @@ -55,7 +55,7 @@ public final class ImmediateEventExecutor extends AbstractEventExecutor { }; private final Future terminationFuture = DefaultPromise.newFailedPromise( - GlobalEventExecutor.INSTANCE, new UnsupportedOperationException()); + GlobalEventExecutor.INSTANCE, new UnsupportedOperationException()).asFuture(); private ImmediateEventExecutor() { } diff --git a/common/src/main/java/io/netty/util/concurrent/MultithreadEventExecutorGroup.java b/common/src/main/java/io/netty/util/concurrent/MultithreadEventExecutorGroup.java index 338a6af9c4..4442740355 100644 --- a/common/src/main/java/io/netty/util/concurrent/MultithreadEventExecutorGroup.java +++ b/common/src/main/java/io/netty/util/concurrent/MultithreadEventExecutorGroup.java @@ -232,7 +232,7 @@ public class MultithreadEventExecutorGroup extends AbstractEventExecutorGroup { @Override public final Future terminationFuture() { - return terminationFuture; + return terminationFuture.asFuture(); } @Override diff --git a/common/src/main/java/io/netty/util/concurrent/Promise.java b/common/src/main/java/io/netty/util/concurrent/Promise.java index 4d963b32a6..3ca0fc4572 100644 --- a/common/src/main/java/io/netty/util/concurrent/Promise.java +++ b/common/src/main/java/io/netty/util/concurrent/Promise.java @@ -15,14 +15,12 @@ */ package io.netty.util.concurrent; -import java.util.concurrent.CancellationException; - /** * Special {@link Future} which is writable. */ -public interface Promise extends Future { +public interface Promise extends AsynchronousResult { /** - * Marks this future as a success and notifies all listeners. + * Marks this promise as a success and notifies all listeners attached to the {@linkplain #asFuture() future}. *

* If it is success or failed already it will throw an {@link IllegalStateException}. */ @@ -31,37 +29,39 @@ public interface Promise extends Future { /** * Marks this future as a success and notifies all listeners. * - * @return {@code true} if and only if successfully marked this future as a success. Otherwise {@code false} because - * this future is already marked as either a success or a failure. + * @return {@code true} if and only if successfully marked this promise as a success. + * Otherwise {@code false} because this promise is already marked as either a success or a failure. */ boolean trySuccess(V result); /** - * Marks this future as a failure and notifies all listeners. + * Marks this promise as a failure and notifies all listeners attached to the {@linkplain #asFuture() future}. *

* If it is success or failed already it will throw an {@link IllegalStateException}. */ Promise setFailure(Throwable cause); /** - * Marks this future as a failure and notifies all listeners. + * Marks this promise as a failure and notifies all listeners. * - * @return {@code true} if and only if successfully marked this future as a failure. Otherwise {@code false} because - * this future is already marked as either a success or a failure. + * @return {@code true} if and only if successfully marked this promise as a failure. + * Otherwise {@code false} because this promise is already marked as either a success or a failure. */ boolean tryFailure(Throwable cause); /** - * Make this future impossible to cancel. + * Make this promise impossible to cancel. * - * @return {@code true} if and only if successfully marked this future as uncancellable, or it is already done - * without being cancelled. Otherwise {@code false} if this future has been cancelled already. + * @return {@code true} if and only if successfully marked this promise as uncancellable, or it is already done + * without being cancelled. Otherwise {@code false} if this promise has been cancelled already. */ boolean setUncancellable(); - @Override - Promise addListener(FutureListener listener); - - @Override - Promise addListener(C context, FutureContextListener listener); + /** + * Return the {@link Future} instance is associated with this promise. + * This future will be completed upon completion of this promise. + * + * @return A future instance associated with this promise. + */ + Future asFuture(); } diff --git a/common/src/main/java/io/netty/util/concurrent/RunnableFutureAdapter.java b/common/src/main/java/io/netty/util/concurrent/RunnableFutureAdapter.java index 3ac1c4bc68..9ba77d8c07 100644 --- a/common/src/main/java/io/netty/util/concurrent/RunnableFutureAdapter.java +++ b/common/src/main/java/io/netty/util/concurrent/RunnableFutureAdapter.java @@ -27,11 +27,13 @@ import java.util.concurrent.TimeoutException; final class RunnableFutureAdapter implements RunnableFuture { private final Promise promise; + private final Future future; private final Callable task; RunnableFutureAdapter(Promise promise, Callable task) { this.promise = requireNonNull(promise, "promise"); this.task = requireNonNull(task, "task"); + future = promise.asFuture(); } @Override @@ -61,58 +63,58 @@ final class RunnableFutureAdapter implements RunnableFuture { @Override public RunnableFuture addListener(FutureListener listener) { - promise.addListener(listener); + future.addListener(listener); return this; } @Override public RunnableFuture addListener(C context, FutureContextListener listener) { - promise.addListener(context, listener); + future.addListener(context, listener); return this; } @Override public RunnableFuture sync() throws InterruptedException { - promise.sync(); + future.sync(); return this; } @Override public RunnableFuture syncUninterruptibly() { - promise.syncUninterruptibly(); + future.syncUninterruptibly(); return this; } @Override public RunnableFuture await() throws InterruptedException { - promise.await(); + future.await(); return this; } @Override public RunnableFuture awaitUninterruptibly() { - promise.awaitUninterruptibly(); + future.awaitUninterruptibly(); return this; } @Override public boolean await(long timeout, TimeUnit unit) throws InterruptedException { - return promise.await(timeout, unit); + return future.await(timeout, unit); } @Override public boolean await(long timeoutMillis) throws InterruptedException { - return promise.await(timeoutMillis); + return future.await(timeoutMillis); } @Override public boolean awaitUninterruptibly(long timeout, TimeUnit unit) { - return promise.awaitUninterruptibly(timeout, unit); + return future.awaitUninterruptibly(timeout, unit); } @Override public boolean awaitUninterruptibly(long timeoutMillis) { - return promise.awaitUninterruptibly(timeoutMillis); + return future.awaitUninterruptibly(timeoutMillis); } @Override @@ -134,7 +136,12 @@ final class RunnableFutureAdapter implements RunnableFuture { @Override public boolean cancel(boolean mayInterruptIfRunning) { - return promise.cancel(mayInterruptIfRunning); + return future.cancel(mayInterruptIfRunning); + } + + @Override + public boolean cancel() { + return cancel(false); } @Override @@ -149,12 +156,12 @@ final class RunnableFutureAdapter implements RunnableFuture { @Override public V get() throws InterruptedException, ExecutionException { - return promise.get(); + return future.get(); } @Override public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { - return promise.get(timeout, unit); + return future.get(timeout, unit); } @Override diff --git a/common/src/main/java/io/netty/util/concurrent/RunnableScheduledFutureAdapter.java b/common/src/main/java/io/netty/util/concurrent/RunnableScheduledFutureAdapter.java index 0a53a3f373..5129ef5a38 100644 --- a/common/src/main/java/io/netty/util/concurrent/RunnableScheduledFutureAdapter.java +++ b/common/src/main/java/io/netty/util/concurrent/RunnableScheduledFutureAdapter.java @@ -41,12 +41,14 @@ final class RunnableScheduledFutureAdapter implements AbstractScheduledEventE private final AbstractScheduledEventExecutor executor; private final Promise promise; + private final Future future; private final Callable callable; RunnableScheduledFutureAdapter(AbstractScheduledEventExecutor executor, Promise promise, Callable callable, long deadlineNanos, long periodNanos) { this.executor = requireNonNull(executor, "executor"); this.promise = requireNonNull(promise, "promise"); + future = promise.asFuture(); this.callable = requireNonNull(callable, "callable"); this.deadlineNanos = deadlineNanos; this.periodNanos = periodNanos; @@ -133,13 +135,18 @@ final class RunnableScheduledFutureAdapter implements AbstractScheduledEventE */ @Override public boolean cancel(boolean mayInterruptIfRunning) { - boolean canceled = promise.cancel(mayInterruptIfRunning); + boolean canceled = future.cancel(mayInterruptIfRunning); if (canceled) { executor.removeScheduled(this); } return canceled; } + @Override + public boolean cancel() { + return cancel(false); + } + @Override public boolean isSuccess() { return promise.isSuccess(); @@ -162,58 +169,58 @@ final class RunnableScheduledFutureAdapter implements AbstractScheduledEventE @Override public RunnableScheduledFuture addListener(FutureListener listener) { - promise.addListener(listener); + future.addListener(listener); return this; } @Override public RunnableScheduledFuture addListener(C context, FutureContextListener listener) { - promise.addListener(context, listener); + future.addListener(context, listener); return this; } @Override public RunnableScheduledFuture sync() throws InterruptedException { - promise.sync(); + future.sync(); return this; } @Override public RunnableScheduledFuture syncUninterruptibly() { - promise.syncUninterruptibly(); + future.syncUninterruptibly(); return this; } @Override public RunnableScheduledFuture await() throws InterruptedException { - promise.await(); + future.await(); return this; } @Override public RunnableScheduledFuture awaitUninterruptibly() { - promise.awaitUninterruptibly(); + future.awaitUninterruptibly(); return this; } @Override public boolean await(long timeout, TimeUnit unit) throws InterruptedException { - return promise.await(timeout, unit); + return future.await(timeout, unit); } @Override public boolean await(long timeoutMillis) throws InterruptedException { - return promise.await(timeoutMillis); + return future.await(timeoutMillis); } @Override public boolean awaitUninterruptibly(long timeout, TimeUnit unit) { - return promise.awaitUninterruptibly(timeout, unit); + return future.awaitUninterruptibly(timeout, unit); } @Override public boolean awaitUninterruptibly(long timeoutMillis) { - return promise.awaitUninterruptibly(timeoutMillis); + return future.awaitUninterruptibly(timeoutMillis); } @Override @@ -228,7 +235,7 @@ final class RunnableScheduledFutureAdapter implements AbstractScheduledEventE @Override public boolean isCancelled() { - return promise.isCancelled(); + return future.isCancelled(); } @Override @@ -238,12 +245,12 @@ final class RunnableScheduledFutureAdapter implements AbstractScheduledEventE @Override public V get() throws InterruptedException, ExecutionException { - return promise.get(); + return future.get(); } @Override public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { - return promise.get(timeout, unit); + return future.get(timeout, unit); } @Override 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 11bc8d5f1d..3bd3515088 100644 --- a/common/src/main/java/io/netty/util/concurrent/SingleThreadEventExecutor.java +++ b/common/src/main/java/io/netty/util/concurrent/SingleThreadEventExecutor.java @@ -546,7 +546,7 @@ public class SingleThreadEventExecutor extends AbstractScheduledEventExecutor im gracefulShutdownTimeout = unit.toNanos(timeout); if (ensureThreadStarted(oldState)) { - return terminationFuture; + return terminationFuture.asFuture(); } if (wakeup) { @@ -561,7 +561,7 @@ public class SingleThreadEventExecutor extends AbstractScheduledEventExecutor im @Override public final Future terminationFuture() { - return terminationFuture; + return terminationFuture.asFuture(); } @Override diff --git a/common/src/main/java/io/netty/util/concurrent/UnaryPromiseNotifier.java b/common/src/main/java/io/netty/util/concurrent/UnaryPromiseNotifier.java index 68faaf33eb..9b5e12d66f 100644 --- a/common/src/main/java/io/netty/util/concurrent/UnaryPromiseNotifier.java +++ b/common/src/main/java/io/netty/util/concurrent/UnaryPromiseNotifier.java @@ -39,7 +39,7 @@ public final class UnaryPromiseNotifier implements FutureListener { logger.warn("Failed to mark a promise as success because it is done already: {}", promise); } } else if (completedFuture.isCancelled()) { - if (!promise.cancel(false)) { + if (!promise.cancel()) { logger.warn("Failed to cancel a promise because it is done already: {}", promise); } } else { diff --git a/common/src/main/java/io/netty/util/concurrent/UnorderedThreadPoolEventExecutor.java b/common/src/main/java/io/netty/util/concurrent/UnorderedThreadPoolEventExecutor.java index b52d4d65f6..7ac16638de 100644 --- a/common/src/main/java/io/netty/util/concurrent/UnorderedThreadPoolEventExecutor.java +++ b/common/src/main/java/io/netty/util/concurrent/UnorderedThreadPoolEventExecutor.java @@ -99,12 +99,13 @@ public final class UnorderedThreadPoolEventExecutor extends ScheduledThreadPoolE @Override public Future newSucceededFuture(V result) { - return DefaultPromise.newSuccessfulPromise(this, result); + return DefaultPromise.newSuccessfulPromise(this, result).asFuture(); } @Override public Future newFailedFuture(Throwable cause) { - return DefaultPromise.newFailedPromise(this, cause); + Promise promise = DefaultPromise.newFailedPromise(this, cause); + return promise.asFuture(); } @Override @@ -140,7 +141,7 @@ public final class UnorderedThreadPoolEventExecutor extends ScheduledThreadPoolE @Override public Future terminationFuture() { - return terminationFuture; + return terminationFuture.asFuture(); } @Override diff --git a/common/src/main/java/io/netty/util/internal/PromiseNotificationUtil.java b/common/src/main/java/io/netty/util/internal/PromiseNotificationUtil.java index 401eebcaaa..a216f0b855 100644 --- a/common/src/main/java/io/netty/util/internal/PromiseNotificationUtil.java +++ b/common/src/main/java/io/netty/util/internal/PromiseNotificationUtil.java @@ -29,7 +29,7 @@ public final class PromiseNotificationUtil { * Try to cancel the {@link Promise} and log if {@code logger} is not {@code null} in case this fails. */ public static void tryCancel(Promise p, InternalLogger logger) { - if (!p.cancel(false) && logger != null) { + if (!p.cancel() && logger != null) { Throwable err = p.cause(); if (err == null) { logger.warn("Failed to cancel promise because it has succeeded already: {}", p); diff --git a/common/src/test/java/io/netty/util/concurrent/DefaultFutureCompletionStageTest.java b/common/src/test/java/io/netty/util/concurrent/DefaultFutureCompletionStageTest.java index 99dacdcff6..d92b70f5ea 100644 --- a/common/src/test/java/io/netty/util/concurrent/DefaultFutureCompletionStageTest.java +++ b/common/src/test/java/io/netty/util/concurrent/DefaultFutureCompletionStageTest.java @@ -79,7 +79,7 @@ public class DefaultFutureCompletionStageTest { public void testSameExecutorAndFuture() { EventExecutor executor = executor(); Promise promise = executor.newPromise(); - FutureCompletionStage stage = new DefaultFutureCompletionStage<>(promise); + FutureCompletionStage stage = new DefaultFutureCompletionStage<>(promise.asFuture()); assertSame(executor, stage.executor()); assertSame(promise, stage.future()); } @@ -88,7 +88,7 @@ public class DefaultFutureCompletionStageTest { public void testThrowsUnsupportedOperationException() { EventExecutor executor = executor(); Promise promise = executor.newPromise(); - FutureCompletionStage stage = new DefaultFutureCompletionStage<>(promise); + FutureCompletionStage stage = new DefaultFutureCompletionStage<>(promise.asFuture()); assertThrows(UnsupportedOperationException.class, () -> stage.toCompletableFuture()); } @@ -766,7 +766,7 @@ public class DefaultFutureCompletionStageTest { // may use different threads. for (int i = 0; i < 1000; i++) { Promise promise = executor.newPromise(); - FutureCompletionStage stage = new DefaultFutureCompletionStage<>(promise); + FutureCompletionStage stage = new DefaultFutureCompletionStage<>(promise.asFuture()); CompletableFuture completableFuture = new CompletableFuture<>(); Future f = fn.apply(stage, completableFuture).future(); diff --git a/common/src/test/java/io/netty/util/concurrent/FuturesTest.java b/common/src/test/java/io/netty/util/concurrent/FuturesTest.java index 0cdceea76b..862e52f213 100644 --- a/common/src/test/java/io/netty/util/concurrent/FuturesTest.java +++ b/common/src/test/java/io/netty/util/concurrent/FuturesTest.java @@ -20,7 +20,6 @@ import org.junit.jupiter.api.Test; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; -import static io.netty.util.concurrent.DefaultPromise.newSuccessfulPromise; import static io.netty.util.concurrent.ImmediateEventExecutor.INSTANCE; import static java.util.concurrent.TimeUnit.SECONDS; import static org.assertj.core.api.Assertions.assertThat; @@ -39,7 +38,7 @@ class FuturesTest { } @Test - public void mapMustApplyMapperFunctionOnSuccededFuture() { + public void mapMustApplyMapperFunctionOnSucceededFuture() { DefaultPromise promise = new DefaultPromise<>(INSTANCE); promise.setSuccess(42); assertThat(promise.map(i -> i.toString()).getNow()).isEqualTo("42"); @@ -108,16 +107,16 @@ class FuturesTest { @Test public void flatMapMustApplyMapperFunctionWhenFutureSucceeds() { DefaultPromise promise = new DefaultPromise<>(INSTANCE); - Future strFut = promise.flatMap(i -> newSuccessfulPromise(INSTANCE, i.toString())); + Future strFut = promise.flatMap(i -> INSTANCE.newSucceededFuture(i.toString())); promise.setSuccess(42); assertThat(strFut.getNow()).isEqualTo("42"); } @Test - public void flatMapMustApplyMapperFunctionOnSuccededFuture() { + public void flatMapMustApplyMapperFunctionOnSucceededFuture() { DefaultPromise promise = new DefaultPromise<>(INSTANCE); promise.setSuccess(42); - assertThat(promise.flatMap(i -> newSuccessfulPromise(INSTANCE, i.toString())).getNow()).isEqualTo("42"); + assertThat(promise.flatMap(i -> INSTANCE.newSucceededFuture(i.toString())).getNow()).isEqualTo("42"); } @Test @@ -125,7 +124,7 @@ class FuturesTest { DefaultPromise promise = new DefaultPromise<>(INSTANCE); Exception cause = new Exception("boom"); promise.setFailure(cause); - assertThat(promise.flatMap(i -> newSuccessfulPromise(INSTANCE, i.toString())).cause()).isSameAs(cause); + assertThat(promise.flatMap(i -> INSTANCE.newSucceededFuture(i.toString())).cause()).isSameAs(cause); } @Test @@ -136,7 +135,7 @@ class FuturesTest { AtomicInteger counter = new AtomicInteger(); assertThat(promise.flatMap(i -> { counter.getAndIncrement(); - return newSuccessfulPromise(INSTANCE, i.toString()); + return INSTANCE.newSucceededFuture(i.toString()); }).cause()).isSameAs(cause); assertThat(counter.get()).isZero(); } @@ -165,7 +164,7 @@ class FuturesTest { @Test public void cancelOnFutureFromFlatMapMustCancelOriginalFuture() { DefaultPromise promise = new DefaultPromise<>(INSTANCE); - Future strFut = promise.flatMap(i -> newSuccessfulPromise(INSTANCE, i.toString())); + Future strFut = promise.flatMap(i -> INSTANCE.newSucceededFuture(i.toString())); strFut.cancel(false); assertTrue(promise.isCancelled()); assertTrue(strFut.isCancelled()); @@ -174,7 +173,7 @@ class FuturesTest { @Test public void cancelOnOriginalFutureMustCancelFutureFromFlatMap() { DefaultPromise promise = new DefaultPromise<>(INSTANCE); - Future strFut = promise.flatMap(i -> newSuccessfulPromise(INSTANCE, i.toString())); + Future strFut = promise.flatMap(i -> INSTANCE.newSucceededFuture(i.toString())); promise.cancel(false); assertTrue(promise.isCancelled()); assertTrue(strFut.isCancelled()); diff --git a/common/src/test/java/io/netty/util/concurrent/PromiseCombinerTest.java b/common/src/test/java/io/netty/util/concurrent/PromiseCombinerTest.java index 7d80a7fc4e..52a701fb5b 100644 --- a/common/src/test/java/io/netty/util/concurrent/PromiseCombinerTest.java +++ b/common/src/test/java/io/netty/util/concurrent/PromiseCombinerTest.java @@ -17,46 +17,30 @@ package io.netty.util.concurrent; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; +import static io.netty.util.concurrent.ImmediateEventExecutor.INSTANCE; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; public class PromiseCombinerTest { - @Mock private Promise p1; - private FutureListener l1; - private final FutureListenerConsumer l1Consumer = new FutureListenerConsumer() { - @Override - public void accept(FutureListener listener) { - l1 = listener; - } - }; - @Mock + private Future f1; private Promise p2; - private FutureListener l2; - private final FutureListenerConsumer l2Consumer = new FutureListenerConsumer() { - @Override - public void accept(FutureListener listener) { - l2 = listener; - } - }; - @Mock + private Future f2; private Promise p3; private PromiseCombiner combiner; @BeforeEach public void setup() { - MockitoAnnotations.initMocks(this); - combiner = new PromiseCombiner(ImmediateEventExecutor.INSTANCE); + p1 = INSTANCE.newPromise(); + p2 = INSTANCE.newPromise(); + p3 = INSTANCE.newPromise(); + f1 = p1.asFuture(); + f2 = p2.asFuture(); + combiner = new PromiseCombiner(INSTANCE); } @Test @@ -68,13 +52,15 @@ public class PromiseCombinerTest { // expected } combiner.finish(p1); - verify(p1).trySuccess(null); + assertTrue(p1.isSuccess()); + assertThat(p1.getNow()).isNull(); } @Test public void testNullAggregatePromise() { combiner.finish(p1); - verify(p1).trySuccess(null); + assertTrue(p1.isSuccess()); + assertThat(p1.getNow()).isNull(); } @Test @@ -90,13 +76,13 @@ public class PromiseCombinerTest { @Test public void testAddAfterFinish() { combiner.finish(p1); - assertThrows(IllegalStateException.class, () -> combiner.add(p2)); + assertThrows(IllegalStateException.class, () -> combiner.add(f2)); } @Test public void testAddAllAfterFinish() { combiner.finish(p1); - assertThrows(IllegalStateException.class, () -> combiner.addAll(p2)); + assertThrows(IllegalStateException.class, () -> combiner.addAll(f2)); } @Test @@ -107,65 +93,59 @@ public class PromiseCombinerTest { @Test public void testAddAllSuccess() throws Exception { - mockSuccessPromise(p1, l1Consumer); - mockSuccessPromise(p2, l2Consumer); - combiner.addAll(p1, p2); + p1.setSuccess(null); + combiner.addAll(f1, f2); combiner.finish(p3); - l1.operationComplete(p1); - verifyNotCompleted(p3); - l2.operationComplete(p2); - verifySuccess(p3); + assertFalse(p3.isDone()); + p2.setSuccess(null); + assertTrue(p3.isDone()); + assertTrue(p3.isSuccess()); } @Test public void testAddSuccess() throws Exception { - mockSuccessPromise(p1, l1Consumer); - mockSuccessPromise(p2, l2Consumer); - combiner.add(p1); - l1.operationComplete(p1); - combiner.add(p2); - l2.operationComplete(p2); - verifyNotCompleted(p3); + p1.setSuccess(null); + p2.setSuccess(null); + combiner.add(f1); + combiner.add(f2); + assertFalse(p3.isDone()); combiner.finish(p3); - verifySuccess(p3); + assertTrue(p3.isSuccess()); } @Test public void testAddAllFail() throws Exception { RuntimeException e1 = new RuntimeException("fake exception 1"); RuntimeException e2 = new RuntimeException("fake exception 2"); - mockFailedPromise(p1, e1, l1Consumer); - mockFailedPromise(p2, e2, l2Consumer); - combiner.addAll(p1, p2); + combiner.addAll(f1, f2); combiner.finish(p3); - l1.operationComplete(p1); - verifyNotCompleted(p3); - l2.operationComplete(p2); - verifyFail(p3, e1); + p1.setFailure(e1); + assertFalse(p3.isDone()); + p2.setFailure(e2); + assertTrue(p3.isFailed()); + assertThat(p3.cause()).isSameAs(e1); } @Test public void testAddFail() throws Exception { RuntimeException e1 = new RuntimeException("fake exception 1"); RuntimeException e2 = new RuntimeException("fake exception 2"); - mockFailedPromise(p1, e1, l1Consumer); - mockFailedPromise(p2, e2, l2Consumer); - combiner.add(p1); - l1.operationComplete(p1); - combiner.add(p2); - l2.operationComplete(p2); - verifyNotCompleted(p3); + combiner.add(f1); + p1.setFailure(e1); + combiner.add(f2); + p2.setFailure(e2); + assertFalse(p3.isDone()); combiner.finish(p3); - verifyFail(p3, e1); + assertTrue(p3.isFailed()); + assertThat(p3.cause()).isSameAs(e1); } @Test public void testEventExecutor() { - EventExecutor executor = mock(EventExecutor.class); - when(executor.inEventLoop()).thenReturn(false); + EventExecutor executor = new SingleThreadEventExecutor(); combiner = new PromiseCombiner(executor); - Future future = mock(Future.class); + Future future = executor.newPromise().asFuture(); try { combiner.add(future); @@ -181,8 +161,7 @@ public class PromiseCombinerTest { // expected } - @SuppressWarnings("unchecked") - Promise promise = (Promise) mock(Promise.class); + Promise promise = executor.newPromise(); try { combiner.finish(promise); fail(); @@ -190,45 +169,4 @@ public class PromiseCombinerTest { // expected } } - - private static void verifyFail(Promise p, Throwable cause) { - verify(p).tryFailure(eq(cause)); - } - - private static void verifySuccess(Promise p) { - verify(p).trySuccess(null); - } - - private static void verifyNotCompleted(Promise p) { - verify(p, never()).trySuccess(any(Void.class)); - verify(p, never()).tryFailure(any(Throwable.class)); - verify(p, never()).setSuccess(any(Void.class)); - verify(p, never()).setFailure(any(Throwable.class)); - } - - private static void mockSuccessPromise(Promise p, FutureListenerConsumer consumer) { - when(p.isDone()).thenReturn(true); - when(p.isSuccess()).thenReturn(true); - mockListener(p, consumer); - } - - private static void mockFailedPromise(Promise p, Throwable cause, FutureListenerConsumer consumer) { - when(p.isDone()).thenReturn(true); - when(p.isSuccess()).thenReturn(false); - when(p.isFailed()).thenReturn(true); - when(p.cause()).thenReturn(cause); - mockListener(p, consumer); - } - - @SuppressWarnings("unchecked") - private static void mockListener(final Promise p, final FutureListenerConsumer consumer) { - doAnswer(invocation -> { - consumer.accept(invocation.getArgument(0)); - return p; - }).when(p).addListener(any(FutureListener.class)); - } - - interface FutureListenerConsumer { - void accept(FutureListener listener); - } } diff --git a/common/src/test/java/io/netty/util/concurrent/SingleThreadEventExecutorTest.java b/common/src/test/java/io/netty/util/concurrent/SingleThreadEventExecutorTest.java index 8eafe64d89..ddfe32587b 100644 --- a/common/src/test/java/io/netty/util/concurrent/SingleThreadEventExecutorTest.java +++ b/common/src/test/java/io/netty/util/concurrent/SingleThreadEventExecutorTest.java @@ -169,7 +169,7 @@ public class SingleThreadEventExecutorTest { promise.setFailure(cause); } }); - promise.syncUninterruptibly(); + promise.asFuture().syncUninterruptibly(); } finally { executor.shutdownGracefully(0, 0, TimeUnit.MILLISECONDS); } diff --git a/example/src/main/java/io/netty/example/http/websocketx/client/WebSocketClientHandler.java b/example/src/main/java/io/netty/example/http/websocketx/client/WebSocketClientHandler.java index 0371a8b56a..868b7062b7 100644 --- a/example/src/main/java/io/netty/example/http/websocketx/client/WebSocketClientHandler.java +++ b/example/src/main/java/io/netty/example/http/websocketx/client/WebSocketClientHandler.java @@ -61,7 +61,7 @@ public class WebSocketClientHandler extends SimpleChannelInboundHandler } public Future handshakeFuture() { - return handshakeFuture; + return handshakeFuture.asFuture(); } @Override diff --git a/example/src/main/java/io/netty/example/http2/helloworld/client/Http2SettingsHandler.java b/example/src/main/java/io/netty/example/http2/helloworld/client/Http2SettingsHandler.java index af409398f8..8127884446 100644 --- a/example/src/main/java/io/netty/example/http2/helloworld/client/Http2SettingsHandler.java +++ b/example/src/main/java/io/netty/example/http2/helloworld/client/Http2SettingsHandler.java @@ -45,7 +45,7 @@ public class Http2SettingsHandler extends SimpleChannelInboundHandler promise = entry.getValue().getValue(); - if (!promise.awaitUninterruptibly(timeout, unit)) { + if (!promise.asFuture().awaitUninterruptibly(timeout, unit)) { throw new IllegalStateException("Timed out waiting for response on stream id " + entry.getKey()); } if (promise.isFailed()) { diff --git a/example/src/main/java/io/netty/example/ocsp/OcspClientExample.java b/example/src/main/java/io/netty/example/ocsp/OcspClientExample.java index 85ab1a5b7b..9f7063fbc7 100644 --- a/example/src/main/java/io/netty/example/ocsp/OcspClientExample.java +++ b/example/src/main/java/io/netty/example/ocsp/OcspClientExample.java @@ -100,7 +100,7 @@ public class OcspClientExample { Channel channel = bootstrap.connect(host, 443).get(); try { - FullHttpResponse response = promise.get(); + FullHttpResponse response = promise.asFuture().get(); ReferenceCountUtil.release(response); } finally { channel.close(); diff --git a/example/src/main/java/io/netty/example/smtp/SmtpClientHandler.java b/example/src/main/java/io/netty/example/smtp/SmtpClientHandler.java index 2b1afc0b1a..8c75ab3d17 100644 --- a/example/src/main/java/io/netty/example/smtp/SmtpClientHandler.java +++ b/example/src/main/java/io/netty/example/smtp/SmtpClientHandler.java @@ -85,6 +85,6 @@ public class SmtpClientHandler extends SimpleChannelInboundHandler throw new RuntimeException("Still waiting for the past response"); } } - return promise.asStage(); + return promise.asFuture().asStage(); } } diff --git a/example/src/main/java/io/netty/example/socksproxy/SocksServerConnectHandler.java b/example/src/main/java/io/netty/example/socksproxy/SocksServerConnectHandler.java index dd694a9a45..ab2973224b 100644 --- a/example/src/main/java/io/netty/example/socksproxy/SocksServerConnectHandler.java +++ b/example/src/main/java/io/netty/example/socksproxy/SocksServerConnectHandler.java @@ -42,23 +42,23 @@ public final class SocksServerConnectHandler extends SimpleChannelInboundHandler if (message instanceof Socks4CommandRequest) { final Socks4CommandRequest request = (Socks4CommandRequest) message; Promise promise = ctx.executor().newPromise(); - promise.addListener(future -> { - final Channel outboundChannel = future.getNow(); - if (future.isSuccess()) { - Future responseFuture = ctx.channel().writeAndFlush( - new DefaultSocks4CommandResponse(Socks4CommandStatus.SUCCESS)); + promise.asFuture().addListener(future -> { + final Channel outboundChannel = future.getNow(); + if (future.isSuccess()) { + Future responseFuture = ctx.channel().writeAndFlush( + new DefaultSocks4CommandResponse(Socks4CommandStatus.SUCCESS)); - responseFuture.addListener(fut -> { - ctx.pipeline().remove(this); - outboundChannel.pipeline().addLast(new RelayHandler(ctx.channel())); - ctx.pipeline().addLast(new RelayHandler(outboundChannel)); - }); - } else { - ctx.channel().writeAndFlush( - new DefaultSocks4CommandResponse(Socks4CommandStatus.REJECTED_OR_FAILED)); - SocksServerUtils.closeOnFlush(ctx.channel()); - } + responseFuture.addListener(fut -> { + ctx.pipeline().remove(this); + outboundChannel.pipeline().addLast(new RelayHandler(ctx.channel())); + ctx.pipeline().addLast(new RelayHandler(outboundChannel)); }); + } else { + ctx.channel().writeAndFlush( + new DefaultSocks4CommandResponse(Socks4CommandStatus.REJECTED_OR_FAILED)); + SocksServerUtils.closeOnFlush(ctx.channel()); + } + }); final Channel inboundChannel = ctx.channel(); b.group(inboundChannel.executor()) @@ -81,27 +81,27 @@ public final class SocksServerConnectHandler extends SimpleChannelInboundHandler } else if (message instanceof Socks5CommandRequest) { final Socks5CommandRequest request = (Socks5CommandRequest) message; Promise promise = ctx.executor().newPromise(); - promise.addListener(future -> { - final Channel outboundChannel = future.getNow(); - if (future.isSuccess()) { - Future responseFuture = - ctx.channel().writeAndFlush(new DefaultSocks5CommandResponse( - Socks5CommandStatus.SUCCESS, - request.dstAddrType(), - request.dstAddr(), - request.dstPort())); - - responseFuture.addListener(fut -> { - ctx.pipeline().remove(this); - outboundChannel.pipeline().addLast(new RelayHandler(ctx.channel())); - ctx.pipeline().addLast(new RelayHandler(outboundChannel)); - }); - } else { + promise.asFuture().addListener(future -> { + final Channel outboundChannel = future.getNow(); + if (future.isSuccess()) { + Future responseFuture = ctx.channel().writeAndFlush(new DefaultSocks5CommandResponse( - Socks5CommandStatus.FAILURE, request.dstAddrType())); - SocksServerUtils.closeOnFlush(ctx.channel()); - } + Socks5CommandStatus.SUCCESS, + request.dstAddrType(), + request.dstAddr(), + request.dstPort())); + + responseFuture.addListener(fut -> { + ctx.pipeline().remove(this); + outboundChannel.pipeline().addLast(new RelayHandler(ctx.channel())); + ctx.pipeline().addLast(new RelayHandler(outboundChannel)); }); + } else { + ctx.channel().writeAndFlush(new DefaultSocks5CommandResponse( + Socks5CommandStatus.FAILURE, request.dstAddrType())); + SocksServerUtils.closeOnFlush(ctx.channel()); + } + }); final Channel inboundChannel = ctx.channel(); b.group(inboundChannel.executor()) diff --git a/handler-proxy/src/main/java/io/netty/handler/proxy/ProxyHandler.java b/handler-proxy/src/main/java/io/netty/handler/proxy/ProxyHandler.java index 22e3a8004a..e915577f98 100644 --- a/handler-proxy/src/main/java/io/netty/handler/proxy/ProxyHandler.java +++ b/handler-proxy/src/main/java/io/netty/handler/proxy/ProxyHandler.java @@ -109,7 +109,7 @@ public abstract class ProxyHandler implements ChannelHandler { * or the connection attempt has failed. */ public final Future connectFuture() { - return connectPromise; + return connectPromise.asFuture(); } /** @@ -396,7 +396,7 @@ public abstract class ProxyHandler implements ChannelHandler { } Promise promise = ctx.newPromise(); addPendingWrite(ctx, msg, promise); - return promise; + return promise.asFuture(); } @Override diff --git a/handler-proxy/src/test/java/io/netty/handler/proxy/HttpProxyHandlerTest.java b/handler-proxy/src/test/java/io/netty/handler/proxy/HttpProxyHandlerTest.java index ff3597feff..2d27eb924d 100644 --- a/handler-proxy/src/test/java/io/netty/handler/proxy/HttpProxyHandlerTest.java +++ b/handler-proxy/src/test/java/io/netty/handler/proxy/HttpProxyHandlerTest.java @@ -40,7 +40,6 @@ import io.netty.handler.codec.http.HttpVersion; import io.netty.handler.proxy.HttpProxyHandler.HttpProxyConnectException; import io.netty.util.NetUtil; import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.Promise; import org.junit.jupiter.api.Test; import java.net.InetAddress; @@ -55,7 +54,6 @@ import static org.mockito.Mockito.isNull; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.same; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; public class HttpProxyHandlerTest { @@ -252,11 +250,10 @@ public class HttpProxyHandlerTest { boolean ignoreDefaultPortsInConnectHostHeader) throws Exception { InetSocketAddress proxyAddress = new InetSocketAddress(NetUtil.LOCALHOST, 8080); - Promise promise = mock(Promise.class); - verifyNoMoreInteractions(promise); + Future future = mock(Future.class); ChannelHandlerContext ctx = mock(ChannelHandlerContext.class); - when(ctx.connect(same(proxyAddress), isNull(InetSocketAddress.class))).thenReturn(promise); + when(ctx.connect(same(proxyAddress), isNull(InetSocketAddress.class))).thenReturn(future); HttpProxyHandler handler = new HttpProxyHandler( new InetSocketAddress(NetUtil.LOCALHOST, 8080), diff --git a/handler/src/main/java/io/netty/handler/address/ResolveAddressHandler.java b/handler/src/main/java/io/netty/handler/address/ResolveAddressHandler.java index fc88c16683..12b01f14d5 100644 --- a/handler/src/main/java/io/netty/handler/address/ResolveAddressHandler.java +++ b/handler/src/main/java/io/netty/handler/address/ResolveAddressHandler.java @@ -23,9 +23,9 @@ import io.netty.resolver.AddressResolverGroup; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.FutureListener; import io.netty.util.concurrent.Promise; -import io.netty.util.internal.ObjectUtil; import java.net.SocketAddress; +import java.util.Objects; /** * {@link ChannelHandler} which will resolve the {@link SocketAddress} that is passed to @@ -38,7 +38,7 @@ public class ResolveAddressHandler implements ChannelHandler { private final AddressResolverGroup resolverGroup; public ResolveAddressHandler(AddressResolverGroup resolverGroup) { - this.resolverGroup = ObjectUtil.checkNotNull(resolverGroup, "resolverGroup"); + this.resolverGroup = Objects.requireNonNull(resolverGroup, "resolverGroup"); } @Override @@ -54,9 +54,9 @@ public class ResolveAddressHandler implements ChannelHandler { } else { ctx.connect(future.getNow(), localAddress).cascadeTo(promise); } - ctx.pipeline().remove(ResolveAddressHandler.this); + ctx.pipeline().remove(this); }); - return promise; + return promise.asFuture(); } else { Future f = ctx.connect(remoteAddress, localAddress); ctx.pipeline().remove(this); diff --git a/handler/src/main/java/io/netty/handler/ssl/SniHandler.java b/handler/src/main/java/io/netty/handler/ssl/SniHandler.java index 5a4fe8d8cc..80f5a80a94 100644 --- a/handler/src/main/java/io/netty/handler/ssl/SniHandler.java +++ b/handler/src/main/java/io/netty/handler/ssl/SniHandler.java @@ -164,9 +164,9 @@ public class SniHandler extends AbstractSniHandler { try { context = mapping.map(input); } catch (Throwable cause) { - return promise.setFailure(cause); + return promise.setFailure(cause).asFuture(); } - return promise.setSuccess(context); + return promise.setSuccess(context).asFuture(); } } diff --git a/handler/src/main/java/io/netty/handler/ssl/SslHandler.java b/handler/src/main/java/io/netty/handler/ssl/SslHandler.java index 4f7034d3e3..c26c596f72 100644 --- a/handler/src/main/java/io/netty/handler/ssl/SslHandler.java +++ b/handler/src/main/java/io/netty/handler/ssl/SslHandler.java @@ -591,7 +591,7 @@ public class SslHandler extends ByteToMessageDecoder { * The {@link Future} for the most recent {@linkplain #renegotiate() TLS renegotiation} otherwise. */ public Future handshakeFuture() { - return handshakePromise; + return handshakePromise.asFuture(); } /** @@ -608,7 +608,7 @@ public class SslHandler extends ByteToMessageDecoder { } else { ctx.executor().execute(() -> closeOutbound0(promise)); } - return promise; + return promise.asFuture(); } private void closeOutbound0(Promise promise) { @@ -631,7 +631,7 @@ public class SslHandler extends ByteToMessageDecoder { * @see SSLEngine */ public Future sslCloseFuture() { - return sslClosePromise; + return sslClosePromise.asFuture(); } @Override @@ -700,7 +700,7 @@ public class SslHandler extends ByteToMessageDecoder { } else { Promise promise = ctx.newPromise(); pendingUnencryptedWrites.add(((ByteBufConvertible) msg).asByteBuf(), promise); - return promise; + return promise.asFuture(); } } @@ -1874,14 +1874,14 @@ public class SslHandler extends ByteToMessageDecoder { // // See https://github.com/netty/netty/issues/5931 Promise cascade = ctx.newPromise(); - cascade.cascadeTo(promise); - safeClose(ctx, closeNotifyPromise, cascade); + cascade.asFuture().cascadeTo(promise); + safeClose(ctx, closeNotifyPromise.asFuture(), cascade); } else { /// We already handling the close_notify so just attach the promise to the sslClosePromise. - sslClosePromise.addListener(future -> promise.setSuccess(null)); + sslCloseFuture().addListener(future -> promise.setSuccess(null)); } } - return promise; + return promise.asFuture(); } private void flush(ChannelHandlerContext ctx, Promise promise) { @@ -1957,15 +1957,15 @@ public class SslHandler extends ByteToMessageDecoder { EventExecutor executor = ctx.executor(); if (!executor.inEventLoop()) { executor.execute(() -> renegotiateOnEventLoop(promise)); - return promise; + return promise.asFuture(); } renegotiateOnEventLoop(promise); - return promise; + return promise.asFuture(); } private void renegotiateOnEventLoop(final Promise newHandshakePromise) { - final Promise oldHandshakePromise = handshakePromise; + Future oldHandshakePromise = handshakeFuture(); if (!oldHandshakePromise.isDone()) { // There's no need to handshake because handshake is in progress already. // Merge the new promise into the old one. @@ -2038,7 +2038,7 @@ public class SslHandler extends ByteToMessageDecoder { }, handshakeTimeoutMillis, TimeUnit.MILLISECONDS); // Cancel the handshake timeout when handshake is finished. - localHandshakePromise.addListener(f -> timeoutFuture.cancel(false)); + localHandshakePromise.asFuture().addListener(f -> timeoutFuture.cancel(false)); } private void forceFlush(ChannelHandlerContext ctx) { @@ -2102,9 +2102,11 @@ public class SslHandler extends ByteToMessageDecoder { } else { Future closeNotifyReadTimeoutFuture; - if (!sslClosePromise.isDone()) { + Future closeFuture = sslCloseFuture(); + + if (!closeFuture.isDone()) { closeNotifyReadTimeoutFuture = ctx.executor().schedule(() -> { - if (!sslClosePromise.isDone()) { + if (!closeFuture.isDone()) { logger.debug( "{} did not receive close_notify in {}ms; force-closing the connection.", ctx.channel(), closeNotifyReadTimeout); @@ -2117,8 +2119,8 @@ public class SslHandler extends ByteToMessageDecoder { closeNotifyReadTimeoutFuture = null; } - // Do the close once the we received the close_notify. - sslClosePromise.addListener(future -> { + // Do the close once we received the close_notify. + closeFuture.addListener(future -> { if (closeNotifyReadTimeoutFuture != null) { closeNotifyReadTimeoutFuture.cancel(false); } diff --git a/handler/src/main/java/io/netty/handler/stream/ChunkedWriteHandler.java b/handler/src/main/java/io/netty/handler/stream/ChunkedWriteHandler.java index 70494fa37b..8bf9ac01ae 100644 --- a/handler/src/main/java/io/netty/handler/stream/ChunkedWriteHandler.java +++ b/handler/src/main/java/io/netty/handler/stream/ChunkedWriteHandler.java @@ -116,7 +116,7 @@ public class ChunkedWriteHandler implements ChannelHandler { public Future write(ChannelHandlerContext ctx, Object msg) { Promise promise = ctx.newPromise(); queue.add(new PendingWrite(msg, promise)); - return promise; + return promise.asFuture(); } @Override @@ -150,10 +150,8 @@ public class ChunkedWriteHandler implements ChannelHandler { if (message instanceof ChunkedInput) { ChunkedInput in = (ChunkedInput) message; boolean endOfInput; - long inputLength; try { endOfInput = in.isEndOfInput(); - inputLength = in.length(); closeInput(in); } catch (Exception e) { closeInput(in); @@ -299,14 +297,10 @@ public class ChunkedWriteHandler implements ChannelHandler { private static void handleEndOfInputFuture(Future future, PendingWrite currentWrite) { ChunkedInput input = (ChunkedInput) currentWrite.msg; + closeInput(input); if (future.isFailed()) { - closeInput(input); currentWrite.fail(future.cause()); } else { - // read state of the input in local variables before closing it - long inputProgress = input.progress(); - long inputLength = input.length(); - closeInput(input); currentWrite.success(); } } diff --git a/handler/src/main/java/io/netty/handler/traffic/AbstractTrafficShapingHandler.java b/handler/src/main/java/io/netty/handler/traffic/AbstractTrafficShapingHandler.java index 2000537c19..bfdcb90530 100644 --- a/handler/src/main/java/io/netty/handler/traffic/AbstractTrafficShapingHandler.java +++ b/handler/src/main/java/io/netty/handler/traffic/AbstractTrafficShapingHandler.java @@ -563,12 +563,12 @@ public abstract class AbstractTrafficShapingHandler implements ChannelHandler { + isHandlerActive(ctx)); } submitWrite(ctx, msg, size, wait, now, promise); - return promise; + return promise.asFuture(); } } // to maintain order of write submitWrite(ctx, msg, size, 0, now, promise); - return promise; + return promise.asFuture(); } @Deprecated diff --git a/handler/src/main/java/io/netty/handler/traffic/GlobalChannelTrafficShapingHandler.java b/handler/src/main/java/io/netty/handler/traffic/GlobalChannelTrafficShapingHandler.java index b2126d8240..8a3de8743c 100644 --- a/handler/src/main/java/io/netty/handler/traffic/GlobalChannelTrafficShapingHandler.java +++ b/handler/src/main/java/io/netty/handler/traffic/GlobalChannelTrafficShapingHandler.java @@ -684,13 +684,13 @@ public class GlobalChannelTrafficShapingHandler extends AbstractTrafficShapingHa } Promise promise = ctx.newPromise(); submitWrite(ctx, msg, size, wait, now, promise); - return promise; + return promise.asFuture(); } } Promise promise = ctx.newPromise(); // to maintain order of write submitWrite(ctx, msg, size, 0, now, promise); - return promise; + return promise.asFuture(); } @Override diff --git a/handler/src/test/java/io/netty/handler/ssl/CipherSuiteCanaryTest.java b/handler/src/test/java/io/netty/handler/ssl/CipherSuiteCanaryTest.java index 2128d692cf..96e8e165a1 100644 --- a/handler/src/test/java/io/netty/handler/ssl/CipherSuiteCanaryTest.java +++ b/handler/src/test/java/io/netty/handler/ssl/CipherSuiteCanaryTest.java @@ -35,6 +35,7 @@ import io.netty.channel.local.LocalServerChannel; import io.netty.handler.ssl.util.InsecureTrustManagerFactory; import io.netty.handler.ssl.util.SelfSignedCertificate; import io.netty.util.ReferenceCountUtil; +import io.netty.util.concurrent.Future; import io.netty.util.concurrent.Promise; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -151,7 +152,7 @@ public class CipherSuiteCanaryTest { pipeline.addLast(new SimpleChannelInboundHandler() { @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { - serverPromise.cancel(true); + serverPromise.cancel(); ctx.fireChannelInactive(); } @@ -187,7 +188,7 @@ public class CipherSuiteCanaryTest { pipeline.addLast(new SimpleChannelInboundHandler() { @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { - clientPromise.cancel(true); + clientPromise.cancel(); ctx.fireChannelInactive(); } @@ -213,11 +214,14 @@ public class CipherSuiteCanaryTest { client.writeAndFlush(Unpooled.wrappedBuffer(new byte[] {'P', 'I', 'N', 'G'})) .syncUninterruptibly(); - assertTrue(clientPromise.await(5L, TimeUnit.SECONDS), "client timeout"); - assertTrue(serverPromise.await(5L, TimeUnit.SECONDS), "server timeout"); + Future clientFuture = clientPromise.asFuture(); + Future serverFuture = serverPromise.asFuture(); - clientPromise.sync(); - serverPromise.sync(); + assertTrue(clientFuture.await(5L, TimeUnit.SECONDS), "client timeout"); + assertTrue(serverFuture.await(5L, TimeUnit.SECONDS), "server timeout"); + + clientFuture.sync(); + serverFuture.sync(); } finally { client.close().sync(); } @@ -260,19 +264,15 @@ public class CipherSuiteCanaryTest { List dst = new ArrayList<>(); SslProvider[] sslProviders = SslProvider.values(); - for (int i = 0; i < sslProviders.length; i++) { - SslProvider serverSslProvider = sslProviders[i]; - - for (int j = 0; j < sslProviders.length; j++) { - SslProvider clientSslProvider = sslProviders[j]; - + for (SslProvider serverSslProvider : sslProviders) { + for (SslProvider clientSslProvider : sslProviders) { if ((serverSslProvider != SslProvider.JDK || clientSslProvider != SslProvider.JDK) - && !OpenSsl.isAvailable()) { + && !OpenSsl.isAvailable()) { continue; } - dst.add(new Object[]{serverSslProvider, clientSslProvider, rfcCipherName, true}); - dst.add(new Object[]{serverSslProvider, clientSslProvider, rfcCipherName, false}); + dst.add(new Object[] { serverSslProvider, clientSslProvider, rfcCipherName, true }); + dst.add(new Object[] { serverSslProvider, clientSslProvider, rfcCipherName, false }); } } diff --git a/handler/src/test/java/io/netty/handler/ssl/OpenSslPrivateKeyMethodTest.java b/handler/src/test/java/io/netty/handler/ssl/OpenSslPrivateKeyMethodTest.java index 993949ce7b..3d8229d405 100644 --- a/handler/src/test/java/io/netty/handler/ssl/OpenSslPrivateKeyMethodTest.java +++ b/handler/src/test/java/io/netty/handler/ssl/OpenSslPrivateKeyMethodTest.java @@ -239,7 +239,7 @@ public class OpenSslPrivateKeyMethodTest { pipeline.addLast(new SimpleChannelInboundHandler() { @Override public void channelInactive(ChannelHandlerContext ctx) { - serverPromise.cancel(true); + serverPromise.cancel(); ctx.fireChannelInactive(); } @@ -275,7 +275,7 @@ public class OpenSslPrivateKeyMethodTest { pipeline.addLast(new SimpleChannelInboundHandler() { @Override public void channelInactive(ChannelHandlerContext ctx) { - clientPromise.cancel(true); + clientPromise.cancel(); ctx.fireChannelInactive(); } @@ -300,11 +300,13 @@ public class OpenSslPrivateKeyMethodTest { client.writeAndFlush(Unpooled.wrappedBuffer(new byte[] {'P', 'I', 'N', 'G'})) .syncUninterruptibly(); - assertTrue(clientPromise.await(5L, TimeUnit.SECONDS), "client timeout"); - assertTrue(serverPromise.await(5L, TimeUnit.SECONDS), "server timeout"); + Future clientFuture = clientPromise.asFuture(); + Future serverFuture = serverPromise.asFuture(); + assertTrue(clientFuture.await(5L, TimeUnit.SECONDS), "client timeout"); + assertTrue(serverFuture.await(5L, TimeUnit.SECONDS), "server timeout"); - clientPromise.sync(); - serverPromise.sync(); + clientFuture.sync(); + serverFuture.sync(); assertTrue(signCalled.get()); } finally { client.close().sync(); @@ -442,7 +444,7 @@ public class OpenSslPrivateKeyMethodTest { } catch (Throwable cause) { promise.setFailure(cause); } - return promise; + return promise.asFuture(); } @Override @@ -470,7 +472,7 @@ public class OpenSslPrivateKeyMethodTest { } catch (Throwable cause) { promise.setFailure(cause); } - return promise; + return promise.asFuture(); } } } diff --git a/handler/src/test/java/io/netty/handler/ssl/ParameterizedSslHandlerTest.java b/handler/src/test/java/io/netty/handler/ssl/ParameterizedSslHandlerTest.java index 73ccc896f4..15af2e1b78 100644 --- a/handler/src/test/java/io/netty/handler/ssl/ParameterizedSslHandlerTest.java +++ b/handler/src/test/java/io/netty/handler/ssl/ParameterizedSslHandlerTest.java @@ -254,7 +254,7 @@ public class ParameterizedSslHandlerTest { } }).connect(sc.localAddress()).get(); - donePromise.get(); + donePromise.asFuture().sync(); } finally { if (cc != null) { cc.close().syncUninterruptibly(); @@ -355,7 +355,7 @@ public class ParameterizedSslHandlerTest { } }).connect(sc.localAddress()).get(); - promise.syncUninterruptibly(); + promise.asFuture().syncUninterruptibly(); } finally { if (cc != null) { cc.close().syncUninterruptibly(); @@ -479,8 +479,8 @@ public class ParameterizedSslHandlerTest { } }).connect(sc.localAddress()).get(); - serverPromise.awaitUninterruptibly(); - clientPromise.awaitUninterruptibly(); + serverPromise.asFuture().awaitUninterruptibly(); + clientPromise.asFuture().awaitUninterruptibly(); // Server always received the close_notify as the client triggers the close sequence. assertTrue(serverPromise.isSuccess()); diff --git a/handler/src/test/java/io/netty/handler/ssl/SSLEngineTest.java b/handler/src/test/java/io/netty/handler/ssl/SSLEngineTest.java index 3b20c8e1ce..f1163ac806 100644 --- a/handler/src/test/java/io/netty/handler/ssl/SSLEngineTest.java +++ b/handler/src/test/java/io/netty/handler/ssl/SSLEngineTest.java @@ -1094,7 +1094,7 @@ public abstract class SSLEngineTest { Future ccf = cb.connect(new InetSocketAddress(expectedHost, port)); assertTrue(ccf.awaitUninterruptibly().isSuccess()); clientChannel = ccf.get(); - return clientWritePromise; + return clientWritePromise.asFuture(); } private void mySetupMutualAuth(SSLEngineTestParam param, File keyFile, File crtFile, String keyPassword) @@ -2000,7 +2000,7 @@ public abstract class SSLEngineTest { }).connect(serverChannel.localAddress()).get(); - promise.syncUninterruptibly(); + promise.asFuture().syncUninterruptibly(); serverCert.delete(); clientCert.delete(); @@ -4029,8 +4029,9 @@ public abstract class SSLEngineTest { out.write(1); out.flush(); - assertTrue(promise.await(10, TimeUnit.SECONDS)); - SecretKey key = promise.get(); + Future future = promise.asFuture(); + assertTrue(future.await(10, TimeUnit.SECONDS)); + SecretKey key = future.get(); assertEquals(48, key.getEncoded().length, "AES secret key must be 48 bytes"); } finally { closeQuietly(socket); diff --git a/handler/src/test/java/io/netty/handler/ssl/SniClientJava8TestUtil.java b/handler/src/test/java/io/netty/handler/ssl/SniClientJava8TestUtil.java index 79d3961392..056a906356 100644 --- a/handler/src/test/java/io/netty/handler/ssl/SniClientJava8TestUtil.java +++ b/handler/src/test/java/io/netty/handler/ssl/SniClientJava8TestUtil.java @@ -152,7 +152,7 @@ final class SniClientJava8TestUtil { Bootstrap cb = new Bootstrap(); cc = cb.group(group).channel(LocalChannel.class).handler(sslHandler).connect(address).get(); - promise.syncUninterruptibly(); + promise.asFuture().syncUninterruptibly(); sslHandler.handshakeFuture().syncUninterruptibly(); } catch (CompletionException e) { throw e.getCause(); diff --git a/handler/src/test/java/io/netty/handler/ssl/SniClientTest.java b/handler/src/test/java/io/netty/handler/ssl/SniClientTest.java index 2f5e064d33..b5ac17d50c 100644 --- a/handler/src/test/java/io/netty/handler/ssl/SniClientTest.java +++ b/handler/src/test/java/io/netty/handler/ssl/SniClientTest.java @@ -139,7 +139,7 @@ public class SniClientTest { SslHandler handler = new SslHandler( sslClientContext.newEngine(ByteBufAllocator.DEFAULT, sniHostName, -1)); cc = cb.group(group).channel(LocalChannel.class).handler(handler).connect(address).get(); - assertEquals(sniHostName, promise.syncUninterruptibly().getNow()); + assertEquals(sniHostName, promise.asFuture().syncUninterruptibly().getNow()); // After we are done with handshaking getHandshakeSession() should return null. handler.handshakeFuture().syncUninterruptibly(); diff --git a/handler/src/test/java/io/netty/handler/ssl/SniHandlerTest.java b/handler/src/test/java/io/netty/handler/ssl/SniHandlerTest.java index 13c7a1731f..a3d69c9c57 100644 --- a/handler/src/test/java/io/netty/handler/ssl/SniHandlerTest.java +++ b/handler/src/test/java/io/netty/handler/ssl/SniHandlerTest.java @@ -537,7 +537,7 @@ public class SniHandlerTest { } finally { if (!success) { ReferenceCountUtil.safeRelease(sslContext); - releasePromise.cancel(true); + releasePromise.cancel(); } } } @@ -569,7 +569,7 @@ public class SniHandlerTest { // The client disconnects cc.close().syncUninterruptibly(); - if (!releasePromise.awaitUninterruptibly(10L, TimeUnit.SECONDS)) { + if (!releasePromise.asFuture().awaitUninterruptibly(10L, TimeUnit.SECONDS)) { throw new IllegalStateException("It doesn't seem #replaceHandler() got called."); } diff --git a/handler/src/test/java/io/netty/handler/ssl/SslErrorTest.java b/handler/src/test/java/io/netty/handler/ssl/SslErrorTest.java index f93706c1b4..e8cee1bfcf 100644 --- a/handler/src/test/java/io/netty/handler/ssl/SslErrorTest.java +++ b/handler/src/test/java/io/netty/handler/ssl/SslErrorTest.java @@ -185,7 +185,7 @@ public class SslErrorTest { } }).connect(serverChannel.localAddress()).get(); // Block until we received the correct exception - promise.syncUninterruptibly(); + promise.asFuture().syncUninterruptibly(); } finally { if (clientChannel != null) { clientChannel.close().syncUninterruptibly(); diff --git a/handler/src/test/java/io/netty/handler/ssl/SslHandlerTest.java b/handler/src/test/java/io/netty/handler/ssl/SslHandlerTest.java index 4ba6e14035..b86da5f617 100644 --- a/handler/src/test/java/io/netty/handler/ssl/SslHandlerTest.java +++ b/handler/src/test/java/io/netty/handler/ssl/SslHandlerTest.java @@ -129,7 +129,7 @@ public class SslHandlerTest { if (((ByteBuf) msg).isReadable()) { Promise promise = ctx.newPromise(); writesToFail.add(promise); - return promise; + return promise.asFuture(); } } return ctx.newSucceededFuture(); @@ -493,8 +493,8 @@ public class SslHandlerTest { sc = serverBootstrap.bind(new InetSocketAddress(0)).get(); cc = bootstrap.connect(sc.localAddress()).get(); - serverPromise.syncUninterruptibly(); - clientPromise.syncUninterruptibly(); + serverPromise.asFuture().syncUninterruptibly(); + clientPromise.asFuture().syncUninterruptibly(); } finally { if (cc != null) { cc.close().syncUninterruptibly(); diff --git a/resolver-dns/src/main/java/io/netty/resolver/dns/Cache.java b/resolver-dns/src/main/java/io/netty/resolver/dns/Cache.java index 263d7ef4aa..515a0e7369 100644 --- a/resolver-dns/src/main/java/io/netty/resolver/dns/Cache.java +++ b/resolver-dns/src/main/java/io/netty/resolver/dns/Cache.java @@ -51,6 +51,11 @@ abstract class Cache { AtomicReferenceFieldUpdater.newUpdater(Cache.Entries.class, FutureAndDelay.class, "expirationFuture"); private static final Future CANCELLED_FUTURE = new Future() { + @Override + public boolean cancel() { + return cancel(false); + } + @Override public boolean isSuccess() { return false; diff --git a/resolver-dns/src/main/java/io/netty/resolver/dns/DnsNameResolver.java b/resolver-dns/src/main/java/io/netty/resolver/dns/DnsNameResolver.java index e895d4e4c3..2fa6994ef6 100644 --- a/resolver-dns/src/main/java/io/netty/resolver/dns/DnsNameResolver.java +++ b/resolver-dns/src/main/java/io/netty/resolver/dns/DnsNameResolver.java @@ -483,7 +483,7 @@ public class DnsNameResolver extends InetNameResolver { }); b.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(maxPayloadSize)); - channelFuture = responseHandler.channelActivePromise; + channelFuture = responseHandler.channelActivePromise.asFuture(); try { ch = b.createUnregistered(); Future future = localAddress == null ? ch.register() : ch.bind(localAddress); @@ -731,10 +731,10 @@ public class DnsNameResolver extends InetNameResolver { DnsRecord[] additionalsArray = toArray(additionals, true); try { doResolve(inetHost, additionalsArray, promise, resolveCache); - return promise; } catch (Exception e) { - return promise.setFailure(e); + promise.setFailure(e); } + return promise.asFuture(); } /** @@ -764,10 +764,10 @@ public class DnsNameResolver extends InetNameResolver { DnsRecord[] additionalsArray = toArray(additionals, true); try { doResolveAll(inetHost, additionalsArray, promise, resolveCache); - return promise; } catch (Exception e) { - return promise.setFailure(e); + promise.setFailure(e); } + return promise.asFuture(); } @Override @@ -858,7 +858,7 @@ public class DnsNameResolver extends InetNameResolver { if (!result.isEmpty()) { trySuccess(promise, result); - return promise; + return promise.asFuture(); } } } @@ -868,7 +868,7 @@ public class DnsNameResolver extends InetNameResolver { dnsServerAddressStreamProvider.nameServerAddressStream(hostname); new DnsRecordResolveContext(this, promise, question, additionals, nameServerAddrs, maxQueriesPerResolve) .resolve(promise); - return promise; + return promise.asFuture(); } private static DnsRecord[] toArray(Iterable additionals, boolean validateType) { @@ -994,7 +994,7 @@ public class DnsNameResolver extends InetNameResolver { DnsCache resolveCache, boolean completeEarlyIfPossible) { final Promise> allPromise = executor().newPromise(); doResolveAllUncached(hostname, additionals, promise, allPromise, resolveCache, true); - allPromise.addListener(future -> { + allPromise.asFuture().addListener(future -> { if (future.isSuccess()) { trySuccess(promise, future.getNow().get(0)); } else { @@ -1225,10 +1225,10 @@ public class DnsNameResolver extends InetNameResolver { try { new DatagramDnsQueryContext(this, nameServerAddr, question, additionals, castPromise) .query(flush, writePromise); - return castPromise; } catch (Exception e) { - return castPromise.setFailure(e); + castPromise.setFailure(e); } + return castPromise.asFuture(); } @SuppressWarnings("unchecked") @@ -1330,7 +1330,7 @@ public class DnsNameResolver extends InetNameResolver { } }); - promise.addListener(addressEnvelopeFuture -> { + promise.asFuture().addListener(addressEnvelopeFuture -> { channel.close(); if (addressEnvelopeFuture.isSuccess()) { diff --git a/resolver-dns/src/main/java/io/netty/resolver/dns/DnsQueryContext.java b/resolver-dns/src/main/java/io/netty/resolver/dns/DnsQueryContext.java index 314fbdf4ea..68c48ead87 100644 --- a/resolver-dns/src/main/java/io/netty/resolver/dns/DnsQueryContext.java +++ b/resolver-dns/src/main/java/io/netty/resolver/dns/DnsQueryContext.java @@ -64,7 +64,7 @@ abstract class DnsQueryContext implements FutureListener { final int initialSearchDomainIdx = startWithoutSearchDomain ? 0 : 1; final Promise> searchDomainPromise = parent.executor().newPromise(); - searchDomainPromise.addListener(new FutureListener>() { + searchDomainPromise.asFuture().addListener(new FutureListener>() { private int searchDomainIdx = initialSearchDomainIdx; @Override public void operationComplete(Future> future) { @@ -220,7 +220,7 @@ abstract class DnsResolveContext { promise.tryFailure(new SearchDomainUnknownHostException(cause, hostname)); } else if (searchDomainIdx < searchDomains.length) { Promise> newPromise = parent.executor().newPromise(); - newPromise.addListener(this); + newPromise.asFuture().addListener(this); doSearchDomainQuery(hostname + '.' + searchDomains[searchDomainIdx++], newPromise); } else if (!startWithoutSearchDomain) { internalResolve(hostname, promise); @@ -421,7 +421,7 @@ abstract class DnsResolveContext { queriesInProgress.add(f); - queryLifecycleObserver.queryWritten(nameServerAddr, writePromise); + queryLifecycleObserver.queryWritten(nameServerAddr, writePromise.asFuture()); f.addListener(future -> { queriesInProgress.remove(future); @@ -475,7 +475,7 @@ abstract class DnsResolveContext { queriesInProgress.add(resolveFuture); Promise> resolverPromise = parent.executor().newPromise(); - resolverPromise.addListener(future -> { + resolverPromise.asFuture().addListener(future -> { // Remove placeholder. queriesInProgress.remove(resolveFuture); diff --git a/resolver-dns/src/main/java/io/netty/resolver/dns/InflightNameResolver.java b/resolver-dns/src/main/java/io/netty/resolver/dns/InflightNameResolver.java index 96c0931c58..bdd671d8fe 100644 --- a/resolver-dns/src/main/java/io/netty/resolver/dns/InflightNameResolver.java +++ b/resolver-dns/src/main/java/io/netty/resolver/dns/InflightNameResolver.java @@ -61,26 +61,27 @@ final class InflightNameResolver implements NameResolver { } @Override - public Promise resolve(String inetHost, Promise promise) { + public Future resolve(String inetHost, Promise promise) { return resolve(resolvesInProgress, inetHost, promise, false); } @Override - public Promise> resolveAll(String inetHost, Promise> promise) { + public Future> resolveAll(String inetHost, Promise> promise) { return resolve(resolveAllsInProgress, inetHost, promise, true); } - private Promise resolve( + private Future resolve( final ConcurrentMap> resolveMap, final String inetHost, final Promise promise, boolean resolveAll) { final Promise earlyPromise = resolveMap.putIfAbsent(inetHost, promise); if (earlyPromise != null) { // Name resolution for the specified inetHost is in progress already. - if (earlyPromise.isDone()) { - transferResult(earlyPromise, promise); + Future earlyFuture = promise.asFuture(); + if (earlyFuture.isDone()) { + transferResult(earlyFuture, promise); } else { - earlyPromise.addListener(f -> transferResult(f, promise)); + earlyFuture.addListener(f -> transferResult(f, promise)); } } else { try { @@ -97,12 +98,12 @@ final class InflightNameResolver implements NameResolver { if (promise.isDone()) { resolveMap.remove(inetHost); } else { - promise.addListener(f -> resolveMap.remove(inetHost)); + promise.asFuture().addListener(f -> resolveMap.remove(inetHost)); } } } - return promise; + return promise.asFuture(); } private static void transferResult(Future src, Promise dst) { diff --git a/resolver-dns/src/test/java/io/netty/resolver/dns/DnsAddressResolverGroupTest.java b/resolver-dns/src/test/java/io/netty/resolver/dns/DnsAddressResolverGroupTest.java index 7cabe994f8..0d25410e08 100644 --- a/resolver-dns/src/test/java/io/netty/resolver/dns/DnsAddressResolverGroupTest.java +++ b/resolver-dns/src/test/java/io/netty/resolver/dns/DnsAddressResolverGroupTest.java @@ -55,7 +55,7 @@ public class DnsAddressResolverGroupTest { promise.setFailure(cause); } }).await(); - promise.sync(); + promise.asFuture().sync(); } finally { resolverGroup.close(); group.shutdownGracefully(); diff --git a/resolver-dns/src/test/java/io/netty/resolver/dns/DnsNameResolverTest.java b/resolver-dns/src/test/java/io/netty/resolver/dns/DnsNameResolverTest.java index c270831923..0867acda6a 100644 --- a/resolver-dns/src/test/java/io/netty/resolver/dns/DnsNameResolverTest.java +++ b/resolver-dns/src/test/java/io/netty/resolver/dns/DnsNameResolverTest.java @@ -3138,7 +3138,7 @@ public class DnsNameResolverTest { final TestDnsServer dnsServer1 = new TestDnsServer(Collections.emptySet()) { @Override protected DnsMessage filterMessage(DnsMessage message) { - promise.cancel(true); + promise.cancel(); return message; } }; diff --git a/resolver/src/main/java/io/netty/resolver/AbstractAddressResolver.java b/resolver/src/main/java/io/netty/resolver/AbstractAddressResolver.java index 9ba6dc2afd..a078b7fee3 100644 --- a/resolver/src/main/java/io/netty/resolver/AbstractAddressResolver.java +++ b/resolver/src/main/java/io/netty/resolver/AbstractAddressResolver.java @@ -104,7 +104,7 @@ public abstract class AbstractAddressResolver implement final T cast = (T) address; final Promise promise = executor().newPromise(); doResolve(cast, promise); - return promise; + return promise.asFuture(); } catch (Exception e) { return executor().newFailedFuture(e); } @@ -117,24 +117,26 @@ public abstract class AbstractAddressResolver implement if (!isSupported(address)) { // Address type not supported by the resolver - return promise.setFailure(new UnsupportedAddressTypeException()); + promise.setFailure(new UnsupportedAddressTypeException()); + return promise.asFuture(); } if (isResolved(address)) { // Resolved already; no need to perform a lookup @SuppressWarnings("unchecked") final T cast = (T) address; - return promise.setSuccess(cast); + promise.setSuccess(cast); + return promise.asFuture(); } try { @SuppressWarnings("unchecked") final T cast = (T) address; doResolve(cast, promise); - return promise; } catch (Exception e) { - return promise.setFailure(e); + promise.setFailure(e); } + return promise.asFuture(); } @Override @@ -156,7 +158,7 @@ public abstract class AbstractAddressResolver implement final T cast = (T) address; final Promise> promise = executor().newPromise(); doResolveAll(cast, promise); - return promise; + return promise.asFuture(); } catch (Exception e) { return executor().newFailedFuture(e); } @@ -169,24 +171,26 @@ public abstract class AbstractAddressResolver implement if (!isSupported(address)) { // Address type not supported by the resolver - return promise.setFailure(new UnsupportedAddressTypeException()); + promise.setFailure(new UnsupportedAddressTypeException()); + return promise.asFuture(); } if (isResolved(address)) { // Resolved already; no need to perform a lookup @SuppressWarnings("unchecked") final T cast = (T) address; - return promise.setSuccess(Collections.singletonList(cast)); + promise.setSuccess(Collections.singletonList(cast)); + return promise.asFuture(); } try { @SuppressWarnings("unchecked") final T cast = (T) address; doResolveAll(cast, promise); - return promise; } catch (Exception e) { - return promise.setFailure(e); + promise.setFailure(e); } + return promise.asFuture(); } /** diff --git a/resolver/src/main/java/io/netty/resolver/SimpleNameResolver.java b/resolver/src/main/java/io/netty/resolver/SimpleNameResolver.java index 4f781fd7e9..8bf0c27619 100644 --- a/resolver/src/main/java/io/netty/resolver/SimpleNameResolver.java +++ b/resolver/src/main/java/io/netty/resolver/SimpleNameResolver.java @@ -59,10 +59,10 @@ public abstract class SimpleNameResolver implements NameResolver { try { doResolve(inetHost, promise); - return promise; } catch (Exception e) { - return promise.setFailure(e); + promise.setFailure(e); } + return promise.asFuture(); } @Override @@ -77,10 +77,10 @@ public abstract class SimpleNameResolver implements NameResolver { try { doResolveAll(inetHost, promise); - return promise; } catch (Exception e) { - return promise.setFailure(e); + promise.setFailure(e); } + return promise.asFuture(); } /** diff --git a/testsuite/src/main/java/io/netty/testsuite/transport/socket/AbstractSocketReuseFdTest.java b/testsuite/src/main/java/io/netty/testsuite/transport/socket/AbstractSocketReuseFdTest.java index c8d68a98e9..3bcc327b31 100644 --- a/testsuite/src/main/java/io/netty/testsuite/transport/socket/AbstractSocketReuseFdTest.java +++ b/testsuite/src/main/java/io/netty/testsuite/transport/socket/AbstractSocketReuseFdTest.java @@ -101,8 +101,8 @@ public abstract class AbstractSocketReuseFdTest extends AbstractSocketTest { cb.connect(sc.localAddress()).addListener(listener); } - clientDonePromise.sync(); - serverDonePromise.sync(); + clientDonePromise.asFuture().sync(); + serverDonePromise.asFuture().sync(); sc.close().sync(); if (globalException.get() != null && !(globalException.get() instanceof IOException)) { diff --git a/testsuite/src/main/java/io/netty/testsuite/transport/socket/DatagramConnectNotExistsTest.java b/testsuite/src/main/java/io/netty/testsuite/transport/socket/DatagramConnectNotExistsTest.java index d7bced7461..af5de77f80 100644 --- a/testsuite/src/main/java/io/netty/testsuite/transport/socket/DatagramConnectNotExistsTest.java +++ b/testsuite/src/main/java/io/netty/testsuite/transport/socket/DatagramConnectNotExistsTest.java @@ -69,7 +69,7 @@ public class DatagramConnectNotExistsTest extends AbstractClientSocketTest { assertTrue(datagramChannel.isActive()); datagramChannel.writeAndFlush( Unpooled.copiedBuffer("test", CharsetUtil.US_ASCII)).syncUninterruptibly(); - assertTrue(promise.syncUninterruptibly().getNow() instanceof PortUnreachableException); + assertTrue(promise.asFuture().syncUninterruptibly().getNow() instanceof PortUnreachableException); } finally { if (datagramChannel != null) { datagramChannel.close(); diff --git a/testsuite/src/main/java/io/netty/testsuite/transport/socket/SocketBufReleaseTest.java b/testsuite/src/main/java/io/netty/testsuite/transport/socket/SocketBufReleaseTest.java index f0f44daa13..a487c25207 100644 --- a/testsuite/src/main/java/io/netty/testsuite/transport/socket/SocketBufReleaseTest.java +++ b/testsuite/src/main/java/io/netty/testsuite/transport/socket/SocketBufReleaseTest.java @@ -22,7 +22,6 @@ import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.util.concurrent.DefaultEventExecutorGroup; -import io.netty.util.concurrent.DefaultPromise; import io.netty.util.concurrent.DefaultThreadFactory; import io.netty.util.concurrent.EventExecutor; import io.netty.util.concurrent.Promise; @@ -55,7 +54,7 @@ public class SocketBufReleaseTest extends AbstractSocketTest { Channel cc = cb.connect(sc.localAddress()).get(); // Ensure the server socket accepted the client connection *and* initialized pipeline successfully. - serverHandler.channelFuture.sync(); + serverHandler.channelFuture.asFuture().sync(); // and then close all sockets. sc.close().sync(); @@ -73,7 +72,7 @@ public class SocketBufReleaseTest extends AbstractSocketTest { private final Random random = new Random(); private final CountDownLatch latch = new CountDownLatch(1); private ByteBuf buf; - private final Promise channelFuture = new DefaultPromise<>(executor); + private final Promise channelFuture = executor.newPromise(); @Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { diff --git a/testsuite/src/main/java/io/netty/testsuite/transport/socket/SocketConnectTest.java b/testsuite/src/main/java/io/netty/testsuite/transport/socket/SocketConnectTest.java index 3bae73c5c7..c0c90cb3ba 100644 --- a/testsuite/src/main/java/io/netty/testsuite/transport/socket/SocketConnectTest.java +++ b/testsuite/src/main/java/io/netty/testsuite/transport/socket/SocketConnectTest.java @@ -78,7 +78,7 @@ public class SocketConnectTest extends AbstractSocketTest { assertLocalAddress((InetSocketAddress) clientChannel.localAddress()); assertNotNull(clientChannel.remoteAddress()); - assertLocalAddress(localAddressPromise.get()); + assertLocalAddress(localAddressPromise.asFuture().get()); } finally { if (clientChannel != null) { clientChannel.close().syncUninterruptibly(); diff --git a/testsuite/src/main/java/io/netty/testsuite/transport/socket/SocketGatheringWriteTest.java b/testsuite/src/main/java/io/netty/testsuite/transport/socket/SocketGatheringWriteTest.java index ddd5155054..7b278f751c 100644 --- a/testsuite/src/main/java/io/netty/testsuite/transport/socket/SocketGatheringWriteTest.java +++ b/testsuite/src/main/java/io/netty/testsuite/transport/socket/SocketGatheringWriteTest.java @@ -151,7 +151,7 @@ public class SocketGatheringWriteTest extends AbstractSocketTest { throw t; } - serverDonePromise.sync(); + serverDonePromise.asFuture().sync(); sh.channel.close().sync(); ch.channel.close().sync(); sc.close().sync(); diff --git a/testsuite/src/main/java/io/netty/testsuite/transport/socket/SocketStringEchoTest.java b/testsuite/src/main/java/io/netty/testsuite/transport/socket/SocketStringEchoTest.java index 1ac5c36a9b..7026e0ddfb 100644 --- a/testsuite/src/main/java/io/netty/testsuite/transport/socket/SocketStringEchoTest.java +++ b/testsuite/src/main/java/io/netty/testsuite/transport/socket/SocketStringEchoTest.java @@ -111,8 +111,8 @@ public class SocketStringEchoTest extends AbstractSocketTest { cc.writeAndFlush(element + delimiter); } - ch.donePromise.sync(); - sh.donePromise.sync(); + ch.donePromise.asFuture().sync(); + sh.donePromise.asFuture().sync(); sh.channel.close().sync(); ch.channel.close().sync(); sc.close().sync(); diff --git a/testsuite/src/main/java/io/netty/testsuite/transport/socket/TrafficShapingHandlerTest.java b/testsuite/src/main/java/io/netty/testsuite/transport/socket/TrafficShapingHandlerTest.java index 49dbb349ab..8d610ca90c 100644 --- a/testsuite/src/main/java/io/netty/testsuite/transport/socket/TrafficShapingHandlerTest.java +++ b/testsuite/src/main/java/io/netty/testsuite/transport/socket/TrafficShapingHandlerTest.java @@ -348,7 +348,7 @@ public class TrafficShapingHandlerTest extends AbstractSocketTest { } cc.flush(); - promise.await(); + promise.asFuture().await(); Long stop = TrafficCounter.milliSecondFromNano(); assertTrue(promise.isSuccess(), "Error during execution of TrafficShapping: " + promise.cause()); 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 ecf70734a3..da160a626f 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 @@ -609,7 +609,7 @@ abstract class AbstractEpollChannel extends AbstractChannel implements UnixChann }, connectTimeoutMillis, TimeUnit.MILLISECONDS); } - promise.addListener(future -> { + promise.asFuture().addListener(future -> { if (future.isCancelled()) { if (connectTimeoutFuture != null) { connectTimeoutFuture.cancel(false); diff --git a/transport-native-epoll/src/main/java/io/netty/channel/epoll/AbstractEpollStreamChannel.java b/transport-native-epoll/src/main/java/io/netty/channel/epoll/AbstractEpollStreamChannel.java index ee6a86679e..25a5b5a02d 100644 --- a/transport-native-epoll/src/main/java/io/netty/channel/epoll/AbstractEpollStreamChannel.java +++ b/transport-native-epoll/src/main/java/io/netty/channel/epoll/AbstractEpollStreamChannel.java @@ -242,7 +242,8 @@ public abstract class AbstractEpollStreamChannel extends AbstractEpollChannel im in.remove(); } return 1; - } else if (flushedAmount == 0) { + } + if (flushedAmount == 0) { validateFileRegion(region, offset); } return WRITE_STATUS_SNDBUF_FULL; @@ -437,7 +438,7 @@ public abstract class AbstractEpollStreamChannel extends AbstractEpollChannel im loop.execute(() -> ((AbstractUnsafe) unsafe()).shutdownOutput(promise)); } - return promise; + return promise.asFuture(); } @Override @@ -458,7 +459,7 @@ public abstract class AbstractEpollStreamChannel extends AbstractEpollChannel im loop.execute(() -> shutdownInput0(promise)); } } - return promise; + return promise.asFuture(); } @Override @@ -474,7 +475,7 @@ public abstract class AbstractEpollStreamChannel extends AbstractEpollChannel im } else { shutdownOutputFuture.addListener(promise, this::shutdownOutputDone); } - return promise; + return promise.asFuture(); } private void shutdownOutputDone(Promise promise, Future shutdownOutputFuture) { diff --git a/transport-native-epoll/src/main/java/io/netty/channel/epoll/EpollDatagramChannel.java b/transport-native-epoll/src/main/java/io/netty/channel/epoll/EpollDatagramChannel.java index b289b26e9b..cb30cdfddf 100644 --- a/transport-native-epoll/src/main/java/io/netty/channel/epoll/EpollDatagramChannel.java +++ b/transport-native-epoll/src/main/java/io/netty/channel/epoll/EpollDatagramChannel.java @@ -149,9 +149,8 @@ public final class EpollDatagramChannel extends AbstractEpollChannel implements } return joinGroup(multicastAddress, iface, null, promise); } catch (IOException e) { - promise.setFailure(e); + return promise.setFailure(e).asFuture(); } - return promise; } @Override @@ -186,7 +185,7 @@ public final class EpollDatagramChannel extends AbstractEpollChannel implements } catch (IOException e) { promise.setFailure(e); } - return promise; + return promise.asFuture(); } @Override @@ -200,9 +199,8 @@ public final class EpollDatagramChannel extends AbstractEpollChannel implements return leaveGroup( multicastAddress, NetworkInterface.getByInetAddress(localAddress().getAddress()), null, promise); } catch (IOException e) { - promise.setFailure(e); + return promise.setFailure(e).asFuture(); } - return promise; } @Override @@ -237,7 +235,7 @@ public final class EpollDatagramChannel extends AbstractEpollChannel implements } catch (IOException e) { promise.setFailure(e); } - return promise; + return promise.asFuture(); } @Override @@ -255,7 +253,7 @@ public final class EpollDatagramChannel extends AbstractEpollChannel implements requireNonNull(sourceToBlock, "sourceToBlock"); requireNonNull(networkInterface, "networkInterface"); promise.setFailure(new UnsupportedOperationException("Multicast not supported")); - return promise; + return promise.asFuture(); } @Override @@ -274,7 +272,7 @@ public final class EpollDatagramChannel extends AbstractEpollChannel implements } catch (Throwable e) { promise.setFailure(e); } - return promise; + return promise.asFuture(); } @Override diff --git a/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/AbstractKQueueChannel.java b/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/AbstractKQueueChannel.java index 1db93a573e..7388c41bb6 100644 --- a/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/AbstractKQueueChannel.java +++ b/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/AbstractKQueueChannel.java @@ -560,7 +560,7 @@ abstract class AbstractKQueueChannel extends AbstractChannel implements UnixChan }, connectTimeoutMillis, TimeUnit.MILLISECONDS); } - promise.addListener(future -> { + promise.asFuture().addListener(future -> { if (future.isCancelled()) { if (connectTimeoutFuture != null) { connectTimeoutFuture.cancel(false); diff --git a/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/AbstractKQueueStreamChannel.java b/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/AbstractKQueueStreamChannel.java index f7e4efbb0a..99c9a4a8e0 100644 --- a/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/AbstractKQueueStreamChannel.java +++ b/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/AbstractKQueueStreamChannel.java @@ -224,7 +224,8 @@ public abstract class AbstractKQueueStreamChannel extends AbstractKQueueChannel in.remove(); } return 1; - } else if (flushedAmount == 0) { + } + if (flushedAmount == 0) { validateFileRegion(region, offset); } return WRITE_STATUS_SNDBUF_FULL; @@ -409,7 +410,7 @@ public abstract class AbstractKQueueStreamChannel extends AbstractKQueueChannel } else { loop.execute(() -> ((AbstractUnsafe) unsafe()).shutdownOutput(promise)); } - return promise; + return promise.asFuture(); } @Override @@ -425,7 +426,7 @@ public abstract class AbstractKQueueStreamChannel extends AbstractKQueueChannel } else { loop.execute(() -> shutdownInput0(promise)); } - return promise; + return promise.asFuture(); } private void shutdownInput0(Promise promise) { @@ -451,7 +452,7 @@ public abstract class AbstractKQueueStreamChannel extends AbstractKQueueChannel } else { shutdownOutputFuture.addListener(promise, this::shutdownOutputDone); } - return promise; + return promise.asFuture(); } private void shutdownOutputDone(Promise promise, Future shutdownOutputFuture) { diff --git a/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/KQueueDatagramChannel.java b/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/KQueueDatagramChannel.java index 0dce1c2193..9528d0b429 100644 --- a/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/KQueueDatagramChannel.java +++ b/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/KQueueDatagramChannel.java @@ -106,9 +106,8 @@ public final class KQueueDatagramChannel extends AbstractKQueueDatagramChannel i } return joinGroup(multicastAddress, iface, null, promise); } catch (SocketException e) { - promise.setFailure(e); + return promise.setFailure(e).asFuture(); } - return promise; } @Override @@ -138,7 +137,7 @@ public final class KQueueDatagramChannel extends AbstractKQueueDatagramChannel i requireNonNull(networkInterface, "networkInterface"); promise.setFailure(new UnsupportedOperationException("Multicast not supported")); - return promise; + return promise.asFuture(); } @Override @@ -152,9 +151,8 @@ public final class KQueueDatagramChannel extends AbstractKQueueDatagramChannel i return leaveGroup( multicastAddress, NetworkInterface.getByInetAddress(localAddress().getAddress()), null, promise); } catch (SocketException e) { - promise.setFailure(e); + return promise.setFailure(e).asFuture(); } - return promise; } @Override @@ -184,8 +182,7 @@ public final class KQueueDatagramChannel extends AbstractKQueueDatagramChannel i requireNonNull(networkInterface, "networkInterface"); promise.setFailure(new UnsupportedOperationException("Multicast not supported")); - - return promise; + return promise.asFuture(); } @Override @@ -203,7 +200,7 @@ public final class KQueueDatagramChannel extends AbstractKQueueDatagramChannel i requireNonNull(sourceToBlock, "sourceToBlock"); requireNonNull(networkInterface, "networkInterface"); promise.setFailure(new UnsupportedOperationException("Multicast not supported")); - return promise; + return promise.asFuture(); } @Override @@ -220,9 +217,8 @@ public final class KQueueDatagramChannel extends AbstractKQueueDatagramChannel i NetworkInterface.getByInetAddress(localAddress().getAddress()), sourceToBlock, promise); } catch (Throwable e) { - promise.setFailure(e); + return promise.setFailure(e).asFuture(); } - return promise; } @Override diff --git a/transport-sctp/src/main/java/io/netty/channel/sctp/nio/NioSctpChannel.java b/transport-sctp/src/main/java/io/netty/channel/sctp/nio/NioSctpChannel.java index b1c6baf4cf..521e320027 100644 --- a/transport-sctp/src/main/java/io/netty/channel/sctp/nio/NioSctpChannel.java +++ b/transport-sctp/src/main/java/io/netty/channel/sctp/nio/NioSctpChannel.java @@ -352,7 +352,7 @@ public class NioSctpChannel extends AbstractNioMessageChannel implements io.nett } else { executor().execute(() -> bindAddress(localAddress, promise)); } - return promise; + return promise.asFuture(); } @Override @@ -372,7 +372,7 @@ public class NioSctpChannel extends AbstractNioMessageChannel implements io.nett } else { executor().execute(() -> unbindAddress(localAddress, promise)); } - return promise; + return promise.asFuture(); } private final class NioSctpChannelConfig extends DefaultSctpChannelConfig { diff --git a/transport-sctp/src/main/java/io/netty/channel/sctp/nio/NioSctpServerChannel.java b/transport-sctp/src/main/java/io/netty/channel/sctp/nio/NioSctpServerChannel.java index 05bb874225..7a87fa4ca0 100644 --- a/transport-sctp/src/main/java/io/netty/channel/sctp/nio/NioSctpServerChannel.java +++ b/transport-sctp/src/main/java/io/netty/channel/sctp/nio/NioSctpServerChannel.java @@ -172,7 +172,7 @@ public class NioSctpServerChannel extends AbstractNioMessageChannel } else { executor().execute(() -> bindAddress(localAddress, promise)); } - return promise; + return promise.asFuture(); } @Override @@ -192,7 +192,7 @@ public class NioSctpServerChannel extends AbstractNioMessageChannel } else { executor().execute(() -> unbindAddress(localAddress, promise)); } - return promise; + return promise.asFuture(); } // Unnecessary stuff diff --git a/transport/src/main/java/io/netty/bootstrap/AbstractBootstrap.java b/transport/src/main/java/io/netty/bootstrap/AbstractBootstrap.java index e229e48ff0..a91ad03800 100644 --- a/transport/src/main/java/io/netty/bootstrap/AbstractBootstrap.java +++ b/transport/src/main/java/io/netty/bootstrap/AbstractBootstrap.java @@ -23,7 +23,6 @@ import io.netty.channel.ChannelOption; import io.netty.channel.EventLoop; import io.netty.channel.EventLoopGroup; import io.netty.util.AttributeKey; -import io.netty.util.concurrent.DefaultPromise; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.Promise; import io.netty.util.internal.SocketUtils; @@ -243,12 +242,12 @@ public abstract class AbstractBootstrap, C return regFuture; } - Promise bindPromise = new DefaultPromise<>(loop); + Promise bindPromise = loop.newPromise(); if (regFuture.isDone()) { // At this point we know that the registration was complete and successful. Channel channel = regFuture.getNow(); Promise promise = channel.newPromise(); - promise.map(v -> channel).cascadeTo(bindPromise); + promise.asFuture().map(v -> channel).cascadeTo(bindPromise); doBind0(regFuture, channel, localAddress, promise); } else { // Registration future is almost always fulfilled already, but just in case it's not. @@ -261,12 +260,12 @@ public abstract class AbstractBootstrap, C } else { Channel channel = future.getNow(); Promise promise = channel.newPromise(); - promise.map(v -> channel).cascadeTo(bindPromise); + promise.asFuture().map(v -> channel).cascadeTo(bindPromise); doBind0(regFuture, channel, localAddress, promise); } }); } - return bindPromise; + return bindPromise.asFuture(); } final Future initAndRegister(EventLoop loop) { @@ -274,10 +273,10 @@ public abstract class AbstractBootstrap, C try { channel = newChannel(loop); } catch (Throwable t) { - return DefaultPromise.newFailedPromise(loop, t); + return loop.newFailedFuture(t); } - Promise promise = new DefaultPromise<>(loop); + Promise promise = loop.newPromise(); loop.execute(() -> init(channel).addListener(future -> { if (future.isSuccess()) { // TODO eventually I think we'd like to be able to either pass the generic promise down, @@ -291,7 +290,7 @@ public abstract class AbstractBootstrap, C } })); - return promise; + return promise.asFuture(); } final Channel initWithoutRegister() throws Exception { diff --git a/transport/src/main/java/io/netty/bootstrap/Bootstrap.java b/transport/src/main/java/io/netty/bootstrap/Bootstrap.java index f4e2442037..13b593d057 100644 --- a/transport/src/main/java/io/netty/bootstrap/Bootstrap.java +++ b/transport/src/main/java/io/netty/bootstrap/Bootstrap.java @@ -26,7 +26,6 @@ import io.netty.resolver.AddressResolver; import io.netty.resolver.AddressResolverGroup; import io.netty.resolver.DefaultAddressResolverGroup; import io.netty.resolver.NameResolver; -import io.netty.util.concurrent.DefaultPromise; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.Promise; import io.netty.util.internal.logging.InternalLogger; @@ -187,7 +186,7 @@ public class Bootstrap extends AbstractBootstrap regFuture = initAndRegister(loop); - Promise resolveAndConnectPromise = new DefaultPromise<>(loop); + Promise resolveAndConnectPromise = loop.newPromise(); if (regFuture.isDone()) { if (regFuture.isFailed()) { return regFuture; @@ -210,7 +209,7 @@ public class Bootstrap extends AbstractBootstrap init(Channel channel) { - Promise promise = new DefaultPromise<>(channel.executor()); + Promise promise = channel.executor().newPromise(); setChannelOptions(channel, newOptionsArray(), logger); setAttributes(channel, newAttributesArray()); @@ -191,7 +190,7 @@ public class ServerBootstrap extends AbstractBootstrap) entry); + aggregatePromise.asFuture().addListener((FutureListener) entry); bufAndListenerPairs.poll(); } return result; @@ -159,7 +159,7 @@ public abstract class AbstractCoalescingBufferQueue { break; } if (entry instanceof FutureListener) { - aggregatePromise.addListener((FutureListener) entry); + aggregatePromise.asFuture().addListener((FutureListener) entry); continue; } entryBuffer = (ByteBuf) entry; diff --git a/transport/src/main/java/io/netty/channel/DefaultChannelHandlerContext.java b/transport/src/main/java/io/netty/channel/DefaultChannelHandlerContext.java index 36a8e4aad2..26820703b8 100644 --- a/transport/src/main/java/io/netty/channel/DefaultChannelHandlerContext.java +++ b/transport/src/main/java/io/netty/channel/DefaultChannelHandlerContext.java @@ -78,7 +78,7 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou ChannelHandler handler) { this.name = requireNonNull(name, "name"); this.pipeline = pipeline; - this.executionMask = mask(handler.getClass()); + executionMask = mask(handler.getClass()); this.handler = handler; } @@ -430,7 +430,7 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou Promise promise = newPromise(); safeExecute(executor, () -> findAndInvokeBind(localAddress).cascadeTo(promise), promise, null); - return promise; + return promise.asFuture(); } @Override @@ -446,7 +446,7 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou } Promise promise = newPromise(); safeExecute(executor, () -> findAndInvokeDeregister().cascadeTo(promise), promise, null); - return promise; + return promise.asFuture(); } private Future findAndInvokeBind(SocketAddress localAddress) { DefaultChannelHandlerContext ctx = findContextOutbound(MASK_BIND); @@ -476,7 +476,7 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou safeExecute(executor, () -> findAndInvokeConnect(remoteAddress, localAddress).cascadeTo(promise), promise, null); - return promise; + return promise.asFuture(); } private Future findAndInvokeConnect(SocketAddress remoteAddress, SocketAddress localAddress) { @@ -509,7 +509,7 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou } Promise promise = newPromise(); safeExecute(executor, () -> findAndInvokeDisconnect().cascadeTo(promise), promise, null); - return promise; + return promise.asFuture(); } private Future findAndInvokeDisconnect() { @@ -536,7 +536,7 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou } Promise promise = newPromise(); safeExecute(executor, () -> findAndInvokeClose().cascadeTo(promise), promise, null); - return promise; + return promise.asFuture(); } private Future findAndInvokeClose() { @@ -563,7 +563,7 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou } Promise promise = newPromise(); safeExecute(executor, () -> findAndInvokeRegister().cascadeTo(promise), promise, null); - return promise; + return promise.asFuture(); } private Future findAndInvokeRegister() { @@ -647,7 +647,7 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou } else { Tasks tasks = invokeTasks(); Promise promise = newPromise(); - promise.addListener(channel(), ChannelFutureListeners.FIRE_EXCEPTION_ON_FAILURE); + promise.asFuture().addListener(channel(), ChannelFutureListeners.FIRE_EXCEPTION_ON_FAILURE); // If flush throws we want to at least propagate the exception through the ChannelPipeline // as otherwise the user will not be made aware of the failure at all. safeExecute(executor, tasks.invokeFlushTask, promise, null); @@ -712,7 +712,7 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou // See https://github.com/netty/netty/issues/8343. task.cancel(); } - return promise; + return promise.asFuture(); } } @@ -820,8 +820,8 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou } } - this.prev = null; - this.next = null; + prev = null; + next = null; } @Override diff --git a/transport/src/main/java/io/netty/channel/DefaultChannelPipeline.java b/transport/src/main/java/io/netty/channel/DefaultChannelPipeline.java index c156f7239b..255ca147c6 100644 --- a/transport/src/main/java/io/netty/channel/DefaultChannelPipeline.java +++ b/transport/src/main/java/io/netty/channel/DefaultChannelPipeline.java @@ -15,11 +15,8 @@ */ package io.netty.channel; -import static java.util.Objects.requireNonNull; - import io.netty.util.ReferenceCountUtil; import io.netty.util.ResourceLeakDetector; -import io.netty.util.concurrent.DefaultPromise; import io.netty.util.concurrent.EventExecutor; import io.netty.util.concurrent.FastThreadLocal; import io.netty.util.concurrent.Future; @@ -42,6 +39,8 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; import java.util.function.IntSupplier; import java.util.function.Predicate; +import static java.util.Objects.requireNonNull; + /** * The default {@link ChannelPipeline} implementation. It is usually created * by a {@link Channel} implementation when the {@link Channel} is created. @@ -78,7 +77,7 @@ public class DefaultChannelPipeline implements ChannelPipeline { public DefaultChannelPipeline(Channel channel) { this.channel = requireNonNull(channel, "channel"); - succeededFuture = DefaultPromise.newSuccessfulPromise(channel.executor(), null); + succeededFuture = channel.executor().newSucceededFuture(null); tail = new DefaultChannelHandlerContext(this, TAIL_NAME, TAIL_HANDLER); head = new DefaultChannelHandlerContext(this, HEAD_NAME, HEAD_HANDLER); @@ -890,7 +889,7 @@ public class DefaultChannelPipeline implements ChannelPipeline { @Override public final Promise newPromise() { - return new DefaultPromise<>(executor()); + return executor().newPromise(); } @Override @@ -900,7 +899,7 @@ public class DefaultChannelPipeline implements ChannelPipeline { @Override public final Future newFailedFuture(Throwable cause) { - return DefaultPromise.newFailedPromise(executor(), cause); + return executor().newFailedFuture(cause); } /** @@ -1045,7 +1044,7 @@ public class DefaultChannelPipeline implements ChannelPipeline { ChannelHandlerContext ctx, SocketAddress localAddress) { Promise promise = ctx.newPromise(); ctx.channel().unsafe().bind(localAddress, promise); - return promise; + return promise.asFuture(); } @Override @@ -1054,35 +1053,35 @@ public class DefaultChannelPipeline implements ChannelPipeline { SocketAddress remoteAddress, SocketAddress localAddress) { Promise promise = ctx.newPromise(); ctx.channel().unsafe().connect(remoteAddress, localAddress, promise); - return promise; + return promise.asFuture(); } @Override public Future disconnect(ChannelHandlerContext ctx) { Promise promise = ctx.newPromise(); ctx.channel().unsafe().disconnect(promise); - return promise; + return promise.asFuture(); } @Override public Future close(ChannelHandlerContext ctx) { Promise promise = ctx.newPromise(); ctx.channel().unsafe().close(promise); - return promise; + return promise.asFuture(); } @Override public Future register(ChannelHandlerContext ctx) { Promise promise = ctx.newPromise(); ctx.channel().unsafe().register(promise); - return promise; + return promise.asFuture(); } @Override public Future deregister(ChannelHandlerContext ctx) { Promise promise = ctx.newPromise(); ctx.channel().unsafe().deregister(promise); - return promise; + return promise.asFuture(); } @Override @@ -1094,7 +1093,7 @@ public class DefaultChannelPipeline implements ChannelPipeline { public Future write(ChannelHandlerContext ctx, Object msg) { Promise promise = ctx.newPromise(); ctx.channel().unsafe().write(msg, promise); - return promise; + return promise.asFuture(); } @Override diff --git a/transport/src/main/java/io/netty/channel/PendingWriteQueue.java b/transport/src/main/java/io/netty/channel/PendingWriteQueue.java index b8a46caa9a..3625068582 100644 --- a/transport/src/main/java/io/netty/channel/PendingWriteQueue.java +++ b/transport/src/main/java/io/netty/channel/PendingWriteQueue.java @@ -152,7 +152,7 @@ public final class PendingWriteQueue { p.setFailure(cause); } assertEmpty(); - return p; + return p.asFuture(); } /** 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 da1655374b..422816cbd0 100644 --- a/transport/src/main/java/io/netty/channel/nio/AbstractNioChannel.java +++ b/transport/src/main/java/io/netty/channel/nio/AbstractNioChannel.java @@ -247,7 +247,7 @@ public abstract class AbstractNioChannel extends AbstractChannel { }, connectTimeoutMillis, TimeUnit.MILLISECONDS); } - promise.addListener(future -> { + promise.asFuture().addListener(future -> { if (future.isCancelled()) { if (connectTimeoutFuture != null) { connectTimeoutFuture.cancel(false); @@ -346,16 +346,6 @@ public abstract class AbstractNioChannel extends AbstractChannel { } } - @Override - protected void doRegister() throws Exception { - executor().unsafe().register(this); - } - - @Override - protected void doDeregister() throws Exception { - executor().unsafe().deregister(this); - } - @Override protected void doBeginRead() throws Exception { // Channel.read() or ChannelHandlerContext.read() was called diff --git a/transport/src/main/java/io/netty/channel/socket/nio/NioDatagramChannel.java b/transport/src/main/java/io/netty/channel/socket/nio/NioDatagramChannel.java index 13ca31d03b..b6a639d98a 100644 --- a/transport/src/main/java/io/netty/channel/socket/nio/NioDatagramChannel.java +++ b/transport/src/main/java/io/netty/channel/socket/nio/NioDatagramChannel.java @@ -368,7 +368,7 @@ public final class NioDatagramChannel } catch (SocketException e) { promise.setFailure(e); } - return promise; + return promise.asFuture(); } @Override @@ -427,7 +427,7 @@ public final class NioDatagramChannel promise.setFailure(e); } - return promise; + return promise.asFuture(); } @Override @@ -443,7 +443,7 @@ public final class NioDatagramChannel } catch (SocketException e) { promise.setFailure(e); } - return promise; + return promise.asFuture(); } @Override @@ -498,7 +498,7 @@ public final class NioDatagramChannel } promise.setSuccess(null); - return promise; + return promise.asFuture(); } /** @@ -539,7 +539,7 @@ public final class NioDatagramChannel } } promise.setSuccess(null); - return promise; + return promise.asFuture(); } /** @@ -564,7 +564,7 @@ public final class NioDatagramChannel } catch (SocketException e) { promise.setFailure(e); } - return promise; + return promise.asFuture(); } void clearReadPending0() { diff --git a/transport/src/main/java/io/netty/channel/socket/nio/NioSocketChannel.java b/transport/src/main/java/io/netty/channel/socket/nio/NioSocketChannel.java index 06aa4047c3..b96d4bd23e 100644 --- a/transport/src/main/java/io/netty/channel/socket/nio/NioSocketChannel.java +++ b/transport/src/main/java/io/netty/channel/socket/nio/NioSocketChannel.java @@ -170,7 +170,7 @@ public class NioSocketChannel extends AbstractNioByteChannel implements io.netty } else { loop.execute(() -> ((AbstractUnsafe) unsafe()).shutdownOutput(promise)); } - return promise; + return promise.asFuture(); } @Override @@ -191,7 +191,7 @@ public class NioSocketChannel extends AbstractNioByteChannel implements io.netty } else { loop.execute(() -> shutdownInput0(promise)); } - return promise; + return promise.asFuture(); } @Override @@ -207,7 +207,7 @@ public class NioSocketChannel extends AbstractNioByteChannel implements io.netty } else { shutdownOutputFuture.addListener(promise, this::shutdownOutputDone); } - return promise; + return promise.asFuture(); } private void shutdownOutputDone(Promise promise, Future shutdownOutputFuture) { diff --git a/transport/src/test/java/io/netty/channel/DefaultChannelPipelineTest.java b/transport/src/test/java/io/netty/channel/DefaultChannelPipelineTest.java index b96d5fd9ed..b46bf38a2e 100644 --- a/transport/src/test/java/io/netty/channel/DefaultChannelPipelineTest.java +++ b/transport/src/test/java/io/netty/channel/DefaultChannelPipelineTest.java @@ -62,7 +62,6 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; public class DefaultChannelPipelineTest { @@ -730,10 +729,10 @@ public class DefaultChannelPipelineTest { CheckEventExecutorHandler handler = new CheckEventExecutorHandler(loop); ChannelPipeline pipeline = newLocalChannel().pipeline(); pipeline.addFirst(handler); - handler.addedPromise.syncUninterruptibly(); + handler.addedFuture.syncUninterruptibly(); pipeline.channel().register(); pipeline.remove(handler); - handler.removedPromise.syncUninterruptibly(); + handler.removedFuture.syncUninterruptibly(); pipeline.channel().close().syncUninterruptibly(); } @@ -747,7 +746,7 @@ public class DefaultChannelPipelineTest { CheckEventExecutorHandler handler = new CheckEventExecutorHandler(loop); ChannelPipeline pipeline = newLocalChannel().pipeline(); pipeline.addFirst(handler); - handler.addedPromise.syncUninterruptibly(); + handler.addedFuture.syncUninterruptibly(); pipeline.channel().register(); pipeline.replace(handler, null, new ChannelHandlerAdapter() { @Override @@ -755,7 +754,7 @@ public class DefaultChannelPipelineTest { latch.countDown(); } }); - handler.removedPromise.syncUninterruptibly(); + handler.removedFuture.syncUninterruptibly(); latch.await(); pipeline.channel().close().syncUninterruptibly(); @@ -878,7 +877,7 @@ public class DefaultChannelPipelineTest { } void validate() { - validationPromise.syncUninterruptibly(); + validationPromise.asFuture().syncUninterruptibly(); validationPromise = ImmediateEventExecutor.INSTANCE.newPromise(); } } @@ -1029,7 +1028,7 @@ public class DefaultChannelPipelineTest { // This event must be captured by the added handler. pipeline.fireUserEventTriggered(event); }); - assertSame(event, promise.syncUninterruptibly().getNow()); + assertSame(event, promise.asFuture().syncUninterruptibly().getNow()); } finally { pipeline1.channel().close().syncUninterruptibly(); } @@ -1569,13 +1568,15 @@ public class DefaultChannelPipelineTest { } private static final class CallbackCheckHandler extends ChannelHandlerAdapter { - final Promise addedHandler = ImmediateEventExecutor.INSTANCE.newPromise(); - final Promise removedHandler = ImmediateEventExecutor.INSTANCE.newPromise(); + private final Promise addedHandlerPromise = ImmediateEventExecutor.INSTANCE.newPromise(); + private final Promise removedHandlerPromise = ImmediateEventExecutor.INSTANCE.newPromise(); + final Future addedHandler = addedHandlerPromise.asFuture(); + final Future removedHandler = removedHandlerPromise.asFuture(); final AtomicReference error = new AtomicReference<>(); @Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { - if (!addedHandler.trySuccess(true)) { + if (!addedHandlerPromise.trySuccess(true)) { error.set(new AssertionError("handlerAdded(...) called multiple times: " + ctx.name())); } else if (removedHandler.isDone() && removedHandler.getNow() == Boolean.TRUE) { error.set(new AssertionError("handlerRemoved(...) called before handlerAdded(...): " + ctx.name())); @@ -1584,7 +1585,7 @@ public class DefaultChannelPipelineTest { @Override public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { - if (!removedHandler.trySuccess(true)) { + if (!removedHandlerPromise.trySuccess(true)) { error.set(new AssertionError("handlerRemoved(...) called multiple times: " + ctx.name())); } else if (addedHandler.isDone() && addedHandler.getNow() == Boolean.FALSE) { error.set(new AssertionError("handlerRemoved(...) called before handlerAdded(...): " + ctx.name())); @@ -1594,13 +1595,17 @@ public class DefaultChannelPipelineTest { private static final class CheckEventExecutorHandler extends ChannelHandlerAdapter { final EventExecutor executor; - final Promise addedPromise; - final Promise removedPromise; + final Future addedFuture; + final Future removedFuture; + private final Promise addedPromise; + private final Promise removedPromise; CheckEventExecutorHandler(EventExecutor executor) { this.executor = executor; addedPromise = executor.newPromise(); + addedFuture = addedPromise.asFuture(); removedPromise = executor.newPromise(); + removedFuture = removedPromise.asFuture(); } @Override diff --git a/transport/src/test/java/io/netty/channel/PendingWriteQueueTest.java b/transport/src/test/java/io/netty/channel/PendingWriteQueueTest.java index 43b016ef96..9499cca8b2 100644 --- a/transport/src/test/java/io/netty/channel/PendingWriteQueueTest.java +++ b/transport/src/test/java/io/netty/channel/PendingWriteQueueTest.java @@ -209,7 +209,7 @@ public class PendingWriteQueueTest { final PendingWriteQueue queue = new PendingWriteQueue(channel.pipeline().firstContext()); Promise promise = channel.newPromise(); - promise.addListener(future -> queue.removeAndFailAll(new IllegalStateException())); + promise.asFuture().addListener(future -> queue.removeAndFailAll(new IllegalStateException())); Promise promise2 = channel.newPromise(); channel.executor().execute(() -> { @@ -239,7 +239,7 @@ public class PendingWriteQueueTest { Promise promise = channel.newPromise(); final Promise promise3 = channel.newPromise(); - promise.addListener(future -> { + promise.asFuture().addListener(future -> { queue.add(3L, promise3); }); Promise promise2 = channel.newPromise(); @@ -277,13 +277,13 @@ public class PendingWriteQueueTest { Promise promise = channel.newPromise(); final Promise promise3 = channel.newPromise(); - promise3.addListener(future -> failOrder.add(3)); - promise.addListener(future -> { + promise3.asFuture().addListener(future -> failOrder.add(3)); + promise.asFuture().addListener(future -> { failOrder.add(1); queue.add(3L, promise3); }); Promise promise2 = channel.newPromise(); - promise2.addListener(future -> failOrder.add(2)); + promise2.asFuture().addListener(future -> failOrder.add(2)); channel.executor().execute(() -> { queue.add(1L, promise); queue.add(2L, promise2); @@ -308,7 +308,7 @@ public class PendingWriteQueueTest { final PendingWriteQueue queue = new PendingWriteQueue(channel.pipeline().firstContext()); Promise promise = channel.newPromise(); - promise.addListener(future -> queue.removeAndWriteAll()); + promise.asFuture().addListener(future -> queue.removeAndWriteAll()); Promise promise2 = channel.newPromise(); channel.executor().execute(() -> { @@ -365,7 +365,7 @@ public class PendingWriteQueueTest { assertFalse(queue.isEmpty()); assertEquals(++expectedSize, queue.size()); assertNotNull(queue.current()); - return promise; + return promise.asFuture(); } @Override diff --git a/transport/src/test/java/io/netty/channel/embedded/EmbeddedChannelTest.java b/transport/src/test/java/io/netty/channel/embedded/EmbeddedChannelTest.java index 369c4b7892..43e23d69b8 100644 --- a/transport/src/test/java/io/netty/channel/embedded/EmbeddedChannelTest.java +++ b/transport/src/test/java/io/netty/channel/embedded/EmbeddedChannelTest.java @@ -343,7 +343,7 @@ public class EmbeddedChannelTest { public Future write(final ChannelHandlerContext ctx, final Object msg) { Promise promise = ctx.newPromise(); ctx.executor().execute(() -> ctx.write(msg).cascadeTo(promise)); - return promise; + return promise.asFuture(); } }); Object msg = new Object(); @@ -364,7 +364,7 @@ public class EmbeddedChannelTest { ctx.executor().schedule(() -> { ctx.writeAndFlush(msg).cascadeTo(promise); }, delay, TimeUnit.MILLISECONDS); - return promise; + return promise.asFuture(); } }); Object msg = new Object(); diff --git a/transport/src/test/java/io/netty/channel/local/LocalChannelTest.java b/transport/src/test/java/io/netty/channel/local/LocalChannelTest.java index 7cd157bf80..df86b27862 100644 --- a/transport/src/test/java/io/netty/channel/local/LocalChannelTest.java +++ b/transport/src/test/java/io/netty/channel/local/LocalChannelTest.java @@ -809,7 +809,7 @@ public class LocalChannelTest { cc.connect(sc.localAddress()).sync(); Future f = ref.get().sync(); - assertPromise.syncUninterruptibly(); + assertPromise.asFuture().syncUninterruptibly(); assertTrue(f.isSuccess()); } finally { closeChannel(cc);