Call ctx.flush() at least once in ChunkedWriteHandler.flush()
Related: #3219 Motivation: ChunkedWriteHandler.flush() does not call ctx.flush() when channel is not writable. This can be a problem when other handler / non-Netty thread writes messages simultaneously, because ChunkedWriteHandler.flush() might have no chance to observe channel.isWritable() returns true and thus the channel is never flushed. Modifications: - Ensure that ChunkedWriteHandler.flush() calls ctx.flush() at least once. Result: A stall connection issue, that occurs when certain combination of handlers exist in a pipeline, has been fixed. (e.g. SslHandler and ChunkedWriteHandler)
This commit is contained in:
parent
a8cee4d649
commit
5edb7083b6
@ -15,8 +15,6 @@
|
||||
*/
|
||||
package io.netty.handler.stream;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufHolder;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelDuplexHandler;
|
||||
@ -136,16 +134,16 @@ public class ChunkedWriteHandler
|
||||
|
||||
@Override
|
||||
public void flush(ChannelHandlerContext ctx) throws Exception {
|
||||
Channel channel = ctx.channel();
|
||||
if (channel.isWritable() || !channel.isActive()) {
|
||||
doFlush(ctx);
|
||||
if (!doFlush(ctx)) {
|
||||
// Make sure to flush at least once.
|
||||
ctx.flush();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
||||
doFlush(ctx);
|
||||
super.channelInactive(ctx);
|
||||
ctx.fireChannelInactive();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -197,12 +195,14 @@ public class ChunkedWriteHandler
|
||||
}
|
||||
}
|
||||
|
||||
private void doFlush(final ChannelHandlerContext ctx) throws Exception {
|
||||
private boolean doFlush(final ChannelHandlerContext ctx) throws Exception {
|
||||
final Channel channel = ctx.channel();
|
||||
if (!channel.isActive()) {
|
||||
discard(null);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean flushed = false;
|
||||
while (channel.isWritable()) {
|
||||
if (currentWrite == null) {
|
||||
currentWrite = queue.poll();
|
||||
@ -307,12 +307,15 @@ public class ChunkedWriteHandler
|
||||
|
||||
// Always need to flush
|
||||
ctx.flush();
|
||||
flushed = true;
|
||||
|
||||
if (!channel.isActive()) {
|
||||
discard(new ClosedChannelException());
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return flushed;
|
||||
}
|
||||
|
||||
static void closeInput(ChunkedInput<?> chunks) {
|
||||
|
Loading…
Reference in New Issue
Block a user