### Question:
NioSocketChannel extends AbstractNioByteChannel implements io.netty.channel.socket.SocketChannel { @Override public InetSocketAddress localAddress() { return (InetSocketAddress) super.localAddress(); } NioSocketChannel();  NioSocketChannel(SelectorProvider provider);  NioSocketChannel(SocketChannel socket);  NioSocketChannel(Channel parent, SocketChannel socket); @Override ServerSocketChannel parent(); @Override SocketChannelConfig config(); @Override boolean isActive(); @Override boolean isOutputShutdown(); @Override boolean isInputShutdown(); @Override boolean isShutdown(); @Override InetSocketAddress localAddress(); @Override InetSocketAddress remoteAddress(); @Override ChannelFuture shutdownOutput(); @Override ChannelFuture shutdownOutput(final ChannelPromise promise); @Override ChannelFuture shutdownInput(); @Override ChannelFuture shutdownInput(final ChannelPromise promise); @Override ChannelFuture shutdown(); @Override ChannelFuture shutdown(final ChannelPromise promise);  }### Answer:
@Test public void testFlushCloseReentrance() throws Exception { NioEventLoopGroup group = new NioEventLoopGroup(1); try { final Queue<ChannelFuture> futures = new LinkedBlockingQueue<ChannelFuture>(); ServerBootstrap sb = new ServerBootstrap(); sb.group(group).channel(NioServerSocketChannel.class); sb.childOption(ChannelOption.SO_SNDBUF, 1024); sb.childHandler(new ChannelInboundHandlerAdapter() { @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { futures.add(ctx.write( ctx.alloc().buffer().writeZero(1048576)).addListener(ChannelFutureListener.CLOSE)); futures.add(ctx.write(ctx.alloc().buffer().writeZero(1048576))); ctx.flush(); futures.add(ctx.write(ctx.alloc().buffer().writeZero(1048576))); ctx.flush(); } }); SocketAddress address = sb.bind(0).sync().channel().localAddress(); Socket s = new Socket(NetUtil.LOCALHOST, ((InetSocketAddress) address).getPort()); InputStream in = s.getInputStream(); byte[] buf = new byte[8192]; for (;;) { if (in.read(buf) == -1) { break; } Thread.sleep(10); } s.close(); assertThat(futures.size(), is(3)); ChannelFuture f1 = futures.poll(); ChannelFuture f2 = futures.poll(); ChannelFuture f3 = futures.poll(); assertThat(f1.isSuccess(), is(true)); assertThat(f2.isDone(), is(true)); assertThat(f2.isSuccess(), is(false)); assertThat(f2.cause(), is(instanceOf(ClosedChannelException.class))); assertThat(f3.isDone(), is(true)); assertThat(f3.isSuccess(), is(false)); assertThat(f3.cause(), is(instanceOf(ClosedChannelException.class))); } finally { group.shutdownGracefully().sync(); } }
@Test public void testFlushAfterGatheredFlush() throws Exception { NioEventLoopGroup group = new NioEventLoopGroup(1); try { ServerBootstrap sb = new ServerBootstrap(); sb.group(group).channel(NioServerSocketChannel.class); sb.childHandler(new ChannelInboundHandlerAdapter() { @Override public void channelActive(final ChannelHandlerContext ctx) throws Exception { ctx.write(Unpooled.wrappedBuffer(new byte[] { 'a' })); ChannelFuture f = ctx.write(Unpooled.wrappedBuffer(new byte[] { 'b' })); f.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { ctx.writeAndFlush(Unpooled.wrappedBuffer(new byte[]{'c'})); } }); ctx.flush(); } }); SocketAddress address = sb.bind(0).sync().channel().localAddress(); Socket s = new Socket(NetUtil.LOCALHOST, ((InetSocketAddress) address).getPort()); DataInput in = new DataInputStream(s.getInputStream()); byte[] buf = new byte[3]; in.readFully(buf); assertThat(new String(buf, CharsetUtil.US_ASCII), is("abc")); s.close(); } finally { group.shutdownGracefully().sync(); } }