diff --git a/handler/src/main/java/io/netty/handler/timeout/ReadTimeoutHandler.java b/handler/src/main/java/io/netty/handler/timeout/ReadTimeoutHandler.java index b6190efb72..66d61ca52d 100644 --- a/handler/src/main/java/io/netty/handler/timeout/ReadTimeoutHandler.java +++ b/handler/src/main/java/io/netty/handler/timeout/ReadTimeoutHandler.java @@ -66,11 +66,13 @@ public class ReadTimeoutHandler extends ChannelInboundHandlerAdapter { private final long timeoutNanos; + private long lastReadTime; + private volatile ScheduledFuture timeout; - private volatile long lastReadTime; private volatile int state; // 0 - none, 1 - Initialized, 2 - Destroyed; + private volatile boolean reading; private boolean closed; /** @@ -146,10 +148,17 @@ public class ReadTimeoutHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - lastReadTime = System.nanoTime(); + reading = true; ctx.fireChannelRead(msg); } + @Override + public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { + lastReadTime = System.nanoTime(); + reading = false; + ctx.fireChannelReadComplete(); + } + private void initialize(ChannelHandlerContext ctx) { // Avoid the case where destroy() is called before scheduling timeouts. // See: https://github.com/netty/netty/issues/143 @@ -204,7 +213,11 @@ public class ReadTimeoutHandler extends ChannelInboundHandlerAdapter { } long currentTime = System.nanoTime(); - long nextDelay = timeoutNanos - (currentTime - lastReadTime); + long nextDelay = timeoutNanos; + if (!reading) { + nextDelay -= currentTime - lastReadTime; + } + if (nextDelay <= 0) { // Read timed out - set a new timeout and notify the callback. timeout = ctx.executor().schedule(this, timeoutNanos, TimeUnit.NANOSECONDS);