mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-25 00:00:18 +02:00
util: fix panics on updating DelayQueue entries (#3270)
This commit is contained in:
@@ -245,6 +245,35 @@ async fn reset_twice() {
|
||||
assert!(queue.is_woken());
|
||||
}
|
||||
|
||||
/// Regression test: Given an entry inserted with a deadline in the past, so
|
||||
/// that it is placed directly on the expired queue, reset the entry to a
|
||||
/// deadline in the future. Validate that this leaves the entry and queue in an
|
||||
/// internally consistent state by running an additional reset on the entry
|
||||
/// before polling it to completion.
|
||||
#[tokio::test]
|
||||
async fn repeatedly_reset_entry_inserted_as_expired() {
|
||||
time::pause();
|
||||
let mut queue = task::spawn(DelayQueue::new());
|
||||
let now = Instant::now();
|
||||
|
||||
let key = queue.insert_at("foo", now - ms(100));
|
||||
|
||||
queue.reset_at(&key, now + ms(100));
|
||||
queue.reset_at(&key, now + ms(50));
|
||||
|
||||
assert_pending!(poll!(queue));
|
||||
|
||||
time::sleep_until(now + ms(60)).await;
|
||||
|
||||
assert!(queue.is_woken());
|
||||
|
||||
let entry = assert_ready_ok!(poll!(queue)).into_inner();
|
||||
assert_eq!(entry, "foo");
|
||||
|
||||
let entry = assert_ready!(poll!(queue));
|
||||
assert!(entry.is_none());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn remove_expired_item() {
|
||||
time::pause();
|
||||
@@ -261,6 +290,38 @@ async fn remove_expired_item() {
|
||||
assert_eq!(entry.into_inner(), "foo");
|
||||
}
|
||||
|
||||
/// Regression test: it should be possible to remove entries which fall in the
|
||||
/// 0th slot of the internal timer wheel — that is, entries whose expiration
|
||||
/// (a) falls at the beginning of one of the wheel's hierarchical levels and (b)
|
||||
/// is equal to the wheel's current elapsed time.
|
||||
#[tokio::test]
|
||||
async fn remove_at_timer_wheel_threshold() {
|
||||
time::pause();
|
||||
|
||||
let mut queue = task::spawn(DelayQueue::new());
|
||||
|
||||
let now = Instant::now();
|
||||
|
||||
let key1 = queue.insert_at("foo", now + ms(64));
|
||||
let key2 = queue.insert_at("bar", now + ms(64));
|
||||
|
||||
sleep(ms(80)).await;
|
||||
|
||||
let entry = assert_ready_ok!(poll!(queue)).into_inner();
|
||||
|
||||
match entry {
|
||||
"foo" => {
|
||||
let entry = queue.remove(&key2).into_inner();
|
||||
assert_eq!(entry, "bar");
|
||||
}
|
||||
"bar" => {
|
||||
let entry = queue.remove(&key1).into_inner();
|
||||
assert_eq!(entry, "foo");
|
||||
}
|
||||
other => panic!("other: {:?}", other),
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn expires_before_last_insert() {
|
||||
time::pause();
|
||||
|
||||
Reference in New Issue
Block a user