Fixed a bug where ChannelReadTimeoutException and ChannelWriteTimeoutException can be raised after a channel is closed.

This commit is contained in:
Trustin Lee 2009-02-11 04:59:45 +00:00
parent bb898265b9
commit 4ea1d640c2
3 changed files with 21 additions and 11 deletions

View File

@ -44,8 +44,8 @@ public class ReadTimeoutHandler extends SimpleChannelUpstreamHandler implements
static final ChannelReadTimeoutException EXCEPTION = new ChannelReadTimeoutException();
final Timer timer;
final long timeoutNanos;
private volatile Timeout timeout;
final long timeoutMillis;
volatile Timeout timeout;
private volatile ReadTimeoutTask task;
volatile long lastReadTime;
@ -63,7 +63,7 @@ public class ReadTimeoutHandler extends SimpleChannelUpstreamHandler implements
}
this.timer = timer;
timeoutNanos = unit.toNanos(timeout);
timeoutMillis = unit.toMillis(timeout);
}
public void releaseExternalResources() {
@ -103,14 +103,14 @@ public class ReadTimeoutHandler extends SimpleChannelUpstreamHandler implements
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
throws Exception {
lastReadTime = System.nanoTime();
lastReadTime = System.currentTimeMillis();
ctx.sendUpstream(e);
}
private void initialize(ChannelHandlerContext ctx) {
lastReadTime = System.nanoTime();
lastReadTime = System.currentTimeMillis();
task = new ReadTimeoutTask(ctx);
timeout = timer.newTimeout(task, timeoutNanos, TimeUnit.NANOSECONDS);
timeout = timer.newTimeout(task, timeoutMillis, TimeUnit.MILLISECONDS);
}
private void destroy() {
@ -134,15 +134,21 @@ public class ReadTimeoutHandler extends SimpleChannelUpstreamHandler implements
return;
}
long currentTime = System.nanoTime();
long nextDelay = timeoutNanos - (currentTime - lastReadTime);
if (!ctx.getChannel().isOpen()) {
return;
}
long currentTime = System.currentTimeMillis();
long nextDelay = timeoutMillis - (currentTime - lastReadTime);
if (nextDelay <= 0) {
// Read timed out - set a new timeout and notify the callback.
timeout = timer.newTimeout(this, timeoutNanos, TimeUnit.NANOSECONDS);
ReadTimeoutHandler.this.timeout =
timer.newTimeout(this, timeoutMillis, TimeUnit.MILLISECONDS);
Channels.fireExceptionCaught(ctx, EXCEPTION);
} else {
// Read occurred before the timer - set a new timeout with shorter delay.
timeout = timer.newTimeout(this, nextDelay, TimeUnit.NANOSECONDS);
ReadTimeoutHandler.this.timeout =
timer.newTimeout(this, nextDelay, TimeUnit.MILLISECONDS);
}
}
}

View File

@ -108,6 +108,10 @@ public class WriteTimeoutHandler extends SimpleChannelDownstreamHandler implemen
return;
}
if (!ctx.getChannel().isOpen()) {
return;
}
// Mark the future as failure
if (future.setFailure(EXCEPTION)) {
// If succeeded to mark as failure, notify the pipeline, too.

View File

@ -37,7 +37,7 @@ import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.MessageEvent;
/**
* A servlet that acts as a proxy for a netty channel
* A Servlet that acts as a proxy for a netty channel
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Andy Taylor (andy.taylor@jboss.org)