From 31a51b4937b782b542023ab92df2fcfb1c51c72c Mon Sep 17 00:00:00 2001 From: Trustin Lee Date: Tue, 21 Aug 2012 20:13:44 +0900 Subject: [PATCH] [#239] IdleStateHandler and ReadTimeoutHandler starts two timers - Ensure initialize does not start timer twice --- .../handler/timeout/IdleStateHandler.java | 29 ++++++++++++------- .../handler/timeout/ReadTimeoutHandler.java | 22 +++++++++----- 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/main/java/org/jboss/netty/handler/timeout/IdleStateHandler.java b/src/main/java/org/jboss/netty/handler/timeout/IdleStateHandler.java index ff591b77dc..22574807b6 100644 --- a/src/main/java/org/jboss/netty/handler/timeout/IdleStateHandler.java +++ b/src/main/java/org/jboss/netty/handler/timeout/IdleStateHandler.java @@ -309,8 +309,13 @@ public class IdleStateHandler extends SimpleChannelUpstreamHandler // Avoid the case where destroy() is called before scheduling timeouts. // See: https://github.com/netty/netty/issues/143 - if (state.destroyed) { - return; + synchronized (state) { + switch (state.state) { + case 1: + case 2: + return; + } + state.state = 1; } state.lastReadTime = state.lastWriteTime = System.currentTimeMillis(); @@ -332,11 +337,12 @@ public class IdleStateHandler extends SimpleChannelUpstreamHandler } private static void destroy(ChannelHandlerContext ctx) { - State state; - - synchronized (ctx) { - state = state(ctx); - state.destroyed = true; + State state = state(ctx); + synchronized (state) { + if (state.state != 1) { + return; + } + state.state = 2; } if (state.readerIdleTimeout != null) { @@ -478,9 +484,8 @@ public class IdleStateHandler extends SimpleChannelUpstreamHandler } private static final class State { - State() { - super(); - } + // 0 - none, 1 - initialized, 2 - destroyed + int state; volatile Timeout readerIdleTimeout; volatile long lastReadTime; @@ -490,6 +495,8 @@ public class IdleStateHandler extends SimpleChannelUpstreamHandler volatile Timeout allIdleTimeout; - volatile boolean destroyed; + State() { + super(); + } } } diff --git a/src/main/java/org/jboss/netty/handler/timeout/ReadTimeoutHandler.java b/src/main/java/org/jboss/netty/handler/timeout/ReadTimeoutHandler.java index 64d56794b1..1b5be683a5 100644 --- a/src/main/java/org/jboss/netty/handler/timeout/ReadTimeoutHandler.java +++ b/src/main/java/org/jboss/netty/handler/timeout/ReadTimeoutHandler.java @@ -189,8 +189,13 @@ public class ReadTimeoutHandler extends SimpleChannelUpstreamHandler // Avoid the case where destroy() is called before scheduling timeouts. // See: https://github.com/netty/netty/issues/143 - if (state.destroyed) { - return; + synchronized (state) { + switch (state.state) { + case 1: + case 2: + return; + } + state.state = 1; } if (timeoutMillis > 0) { @@ -199,10 +204,12 @@ public class ReadTimeoutHandler extends SimpleChannelUpstreamHandler } private static void destroy(ChannelHandlerContext ctx) { - State state; - synchronized (ctx) { - state = state(ctx); - state.destroyed = true; + State state = state(ctx); + synchronized (state) { + if (state.state != 1) { + return; + } + state.state = 2; } if (state.timeout != null) { @@ -269,9 +276,10 @@ public class ReadTimeoutHandler extends SimpleChannelUpstreamHandler } private static final class State { + // 0 - none, 1 - initialized, 2 - destroyed + int state; volatile Timeout timeout; volatile long lastReadTime = System.currentTimeMillis(); - volatile boolean destroyed; State() { super();