NETTY-431 HashedWheelTimer's TimerTask may execute after call to Timeout.cancel()

* Replaced a volatile boolean flag and system date access with an atomic integer flag.
This commit is contained in:
Trustin Lee 2011-08-12 14:03:48 +09:00
parent 1345a00a1a
commit 58cc6aec86

View File

@ -472,11 +472,15 @@ public class HashedWheelTimer implements Timer {
private final class HashedWheelTimeout implements Timeout {
private static final int ST_INIT = 0;
private static final int ST_CANCELLED = 1;
private static final int ST_EXPIRED = 2;
private final TimerTask task;
final long deadline;
volatile int stopIndex;
volatile long remainingRounds;
private volatile boolean cancelled;
private final AtomicInteger state = new AtomicInteger(ST_INIT);
HashedWheelTimeout(TimerTask task, long deadline) {
this.task = task;
@ -492,26 +496,24 @@ public class HashedWheelTimer implements Timer {
}
public void cancel() {
if (isExpired()) {
if (!state.compareAndSet(ST_INIT, ST_CANCELLED)) {
// TODO return false
return;
}
cancelled = true;
// Might be called more than once, but doesn't matter.
wheel[stopIndex].remove(this);
}
public boolean isCancelled() {
return cancelled;
return state.get() == ST_CANCELLED;
}
public boolean isExpired() {
return cancelled || System.currentTimeMillis() > deadline;
return state.get() != ST_INIT;
}
public void expire() {
if (cancelled) {
if (!state.compareAndSet(ST_INIT, ST_EXPIRED)) {
return;
}