From 49b0d6ed07c50aed9c72076b0c299bdb03b0631f Mon Sep 17 00:00:00 2001 From: Scott Mitchell Date: Fri, 29 May 2015 16:27:59 -0700 Subject: [PATCH] HTTP/2 ConnectionHandler close cleanup Motiviation: The connection handler stream close operation is unconditionally adding a listener object to a future. We may not have to add a listener at all because the future has already been completed. Modifications: - If the future is done, directly invoke the logic without creating/adding a new listener. Result: No need to create/add listener if the future is already done in close logic. --- .../codec/http2/Http2ConnectionHandler.java | 42 +++++++++++++------ 1 file changed, 29 insertions(+), 13 deletions(-) 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 cde0b4bcbc..c10cc4742d 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 @@ -481,20 +481,16 @@ public class Http2ConnectionHandler extends ByteToMessageDecoder implements Http public void closeStream(final Http2Stream stream, ChannelFuture future) { stream.close(); - future.addListener(new ChannelFutureListener() { - @Override - public void operationComplete(ChannelFuture future) throws Exception { - // If this connection is closing and the graceful shutdown has completed, close the connection - // once this operation completes. - if (closeListener != null && isGracefulShutdownComplete()) { - ChannelFutureListener closeListener = Http2ConnectionHandler.this.closeListener; - // This method could be called multiple times - // and we don't want to notify the closeListener multiple times. - Http2ConnectionHandler.this.closeListener = null; - closeListener.operationComplete(future); + if (future.isDone()) { + checkCloseConnection(future); + } else { + future.addListener(new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) throws Exception { + checkCloseConnection(future); } - } - }); + }); + } } /** @@ -623,6 +619,26 @@ public class Http2ConnectionHandler extends ByteToMessageDecoder implements Http } } + /** + * Closes the connection if the graceful shutdown process has completed. + * @param future Represents the status that will be passed to the {@link #closeListener}. + */ + private void checkCloseConnection(ChannelFuture future) { + // If this connection is closing and the graceful shutdown has completed, close the connection + // once this operation completes. + if (closeListener != null && isGracefulShutdownComplete()) { + ChannelFutureListener closeListener = Http2ConnectionHandler.this.closeListener; + // This method could be called multiple times + // and we don't want to notify the closeListener multiple times. + Http2ConnectionHandler.this.closeListener = null; + try { + closeListener.operationComplete(future); + } catch (Exception e) { + throw new IllegalStateException("Close listener threw an unexpected exception", e); + } + } + } + /** * Gets the initial settings to be sent to the remote endpoint. */