[#1959] Proposed fix to correctly handle timeouts that overflow the ticks in the wheel

This commit is contained in:
Norman Maurer 2013-10-30 21:50:36 +01:00
parent d6cc74d8cd
commit 285dd79a10
2 changed files with 24 additions and 2 deletions

View File

@ -485,9 +485,10 @@ public class HashedWheelTimer implements Timer {
this.task = task;
this.deadline = deadline;
final long ticks = Math.max(deadline / tickDuration, tick); // Ensure we don't schedule for past.
long calculated = deadline / tickDuration;
final long ticks = Math.max(calculated, tick); // Ensure we don't schedule for past.
stopIndex = (int) (ticks & mask);
remainingRounds = ticks / wheel.length;
remainingRounds = (calculated - tick) / wheel.length;
}
@Override

View File

@ -16,8 +16,12 @@
package io.netty.util;
import org.junit.Test;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@ -102,4 +106,21 @@ public class HashedWheelTimerTest {
}
}, 1, TimeUnit.SECONDS);
}
@Test
public void testTimerOverflowWheelLength() throws InterruptedException {
final HashedWheelTimer timer = new HashedWheelTimer(
Executors.defaultThreadFactory(), 100, TimeUnit.MILLISECONDS, 32);
final AtomicInteger counter = new AtomicInteger();
timer.newTimeout(new TimerTask() {
@Override
public void run(final Timeout timeout) throws Exception {
counter.incrementAndGet();
timer.newTimeout(this, 1, TimeUnit.SECONDS);
}
}, 1, TimeUnit.SECONDS);
Thread.sleep(3500);
assertEquals(3, counter.get());
}
}