@Override public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { if (channelBuffer.refCnt() >= 1) { channelBuffer.release(); } super.handlerRemoved(ctx); }
@Test public void shouldFireChannelWritabilityChangedAfterRemoval() { final AtomicReference<ChannelHandlerContext> ctxRef = new AtomicReference<ChannelHandlerContext>(); final AtomicReference<PendingWriteQueue> queueRef = new AtomicReference<PendingWriteQueue>(); final ByteBuf msg = Unpooled.copiedBuffer("test", CharsetUtil.US_ASCII); final EmbeddedChannel channel = new EmbeddedChannel( new ChannelHandlerAdapter() { @Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { ctxRef.set(ctx); queueRef.set(new PendingWriteQueue(ctx)); } @Override public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception { final PendingWriteQueue queue = queueRef.get(); final ByteBuf msg = (ByteBuf) queue.current(); if (msg == null) { return; } assertThat(msg.refCnt(), is(1)); // This call will trigger another channelWritabilityChanged() event because the // number of // pending bytes will go below the low watermark. // // If PendingWriteQueue.remove() did not remove the current entry before triggering // channelWritabilityChanged() event, we will end up with attempting to remove the // same // element twice, resulting in the double release. queue.remove(); assertThat(msg.refCnt(), is(0)); } }); channel.config().setWriteBufferLowWaterMark(1); channel.config().setWriteBufferHighWaterMark(3); final PendingWriteQueue queue = queueRef.get(); // Trigger channelWritabilityChanged() by adding a message that's larger than the high // watermark. queue.add(msg, channel.newPromise()); channel.finish(); assertThat(msg.refCnt(), is(0)); }
@Test public void echo() { String m = "echo test\n"; EmbeddedChannel ch = new EmbeddedChannel(new EchoServerHandler()); ByteBuf in = Unpooled.copiedBuffer(m, CharsetUtil.UTF_8); ch.writeInbound(in); ByteBuf r = (ByteBuf) ch.readOutbound(); releaseLater(r); assertThat("응답이 없습니다", r, notNullValue()); assertThat("참조수는 1이어야 합니다", r.refCnt(), is(1)); assertThat("수신한 텍스트가 결과로 와야합니다", r.toString(CharsetUtil.UTF_8), equalTo(m)); }
private void handleError(@NotNull FastCgiRequest fastCgiRequest, @Nullable ByteBuf content) { try { if (content != null && content.refCnt() != 0) { content.release(); } } finally { Channel channel = requests.remove(fastCgiRequest.requestId); if (channel != null) { sendBadGateway(channel); } } }
@Override public int refCnt() { return buf.refCnt(); }
@Override public int refCnt() { return content.refCnt(); }