mirror of
https://github.com/tokio-rs/tokio.git
synced 2025-10-01 12:20:39 +00:00
parent
61d4aa98e4
commit
13c96187f8
@ -342,7 +342,7 @@ impl<T> DelayQueue<T> {
|
|||||||
let should_set_delay = if let Some(ref delay) = self.delay {
|
let should_set_delay = if let Some(ref delay) = self.delay {
|
||||||
let current_exp = self.normalize_deadline(delay.deadline());
|
let current_exp = self.normalize_deadline(delay.deadline());
|
||||||
current_exp > when
|
current_exp > when
|
||||||
} else { false };
|
} else { true };
|
||||||
|
|
||||||
if should_set_delay {
|
if should_set_delay {
|
||||||
self.delay = Some(self.handle.delay(self.start + Duration::from_millis(when)));
|
self.delay = Some(self.handle.delay(self.start + Duration::from_millis(when)));
|
||||||
@ -507,24 +507,18 @@ impl<T> DelayQueue<T> {
|
|||||||
// Normalize the deadline. Values cannot be set to expire in the past.
|
// Normalize the deadline. Values cannot be set to expire in the past.
|
||||||
let when = self.normalize_deadline(when);
|
let when = self.normalize_deadline(when);
|
||||||
|
|
||||||
// This is needed only for the debug assertion inside the if-let.
|
|
||||||
let old = self.start + Duration::from_millis(self.slab[key.index].when);
|
|
||||||
|
|
||||||
self.slab[key.index].when = when;
|
self.slab[key.index].when = when;
|
||||||
|
|
||||||
if let Some(ref mut delay) = self.delay {
|
|
||||||
debug_assert!(old >= delay.deadline());
|
|
||||||
|
|
||||||
let start = self.start;
|
|
||||||
let next_poll = self.wheel.poll_at()
|
|
||||||
.map(move |t| start + Duration::from_millis(t));
|
|
||||||
|
|
||||||
if next_poll != Some(delay.deadline()) {
|
|
||||||
delay.reset(self.start + Duration::from_millis(when));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.insert_idx(when, key.index);
|
self.insert_idx(when, key.index);
|
||||||
|
|
||||||
|
let next_deadline = self.next_deadline();
|
||||||
|
if let (Some(ref mut delay), Some(deadline)) = (&mut self.delay, next_deadline) {
|
||||||
|
delay.reset(deadline);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the next time poll as determined by the wheel
|
||||||
|
fn next_deadline(&mut self) -> Option<Instant> {
|
||||||
|
self.wheel.poll_at().map(|poll_at| self.start + Duration::from_millis(poll_at))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the delay of the item associated with `key` to expire after
|
/// Sets the delay of the item associated with `key` to expire after
|
||||||
@ -694,14 +688,12 @@ impl<T> DelayQueue<T> {
|
|||||||
return Ok(Some(idx).into());
|
return Ok(Some(idx).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let deadline = match self.wheel.poll_at() {
|
if let Some(deadline) = self.next_deadline() {
|
||||||
Some(poll_at) => {
|
|
||||||
self.start + Duration::from_millis(poll_at)
|
|
||||||
}
|
|
||||||
None => return Ok(None.into()),
|
|
||||||
};
|
|
||||||
|
|
||||||
self.delay = Some(self.handle.delay(deadline));
|
self.delay = Some(self.handle.delay(deadline));
|
||||||
|
} else {
|
||||||
|
return Ok(None.into())
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,3 +311,99 @@ fn expires_before_last_insert() {
|
|||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn multi_reset() {
|
||||||
|
mocked(|_, time| {
|
||||||
|
let mut queue = DelayQueue::new();
|
||||||
|
let mut task = MockTask::new();
|
||||||
|
|
||||||
|
let epoch = time.now();
|
||||||
|
|
||||||
|
let foo = queue.insert_at("foo", epoch + ms(200));
|
||||||
|
let bar = queue.insert_at("bar", epoch + ms(250));
|
||||||
|
|
||||||
|
task.enter(|| {
|
||||||
|
assert_not_ready!(queue);
|
||||||
|
});
|
||||||
|
|
||||||
|
queue.reset_at(&foo, epoch + ms(300));
|
||||||
|
queue.reset_at(&bar, epoch + ms(350));
|
||||||
|
queue.reset_at(&foo, epoch + ms(400));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn expire_first_key_when_reset_to_expire_earlier() {
|
||||||
|
mocked(|timer, time| {
|
||||||
|
let mut queue = DelayQueue::new();
|
||||||
|
let mut task = MockTask::new();
|
||||||
|
|
||||||
|
let epoch = time.now();
|
||||||
|
|
||||||
|
let foo = queue.insert_at("foo", epoch + ms(200));
|
||||||
|
queue.insert_at("bar", epoch + ms(250));
|
||||||
|
|
||||||
|
task.enter(|| {
|
||||||
|
assert_not_ready!(queue);
|
||||||
|
});
|
||||||
|
|
||||||
|
queue.reset_at(&foo, epoch + ms(100));
|
||||||
|
|
||||||
|
advance(timer, ms(100));
|
||||||
|
|
||||||
|
assert!(task.is_notified());
|
||||||
|
let entry = assert_ready!(queue).unwrap().into_inner();
|
||||||
|
assert_eq!(entry, "foo");
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn expire_second_key_when_reset_to_expire_earlier() {
|
||||||
|
mocked(|timer, time| {
|
||||||
|
let mut queue = DelayQueue::new();
|
||||||
|
let mut task = MockTask::new();
|
||||||
|
|
||||||
|
let epoch = time.now();
|
||||||
|
|
||||||
|
queue.insert_at("foo", epoch + ms(200));
|
||||||
|
let bar = queue.insert_at("bar", epoch + ms(250));
|
||||||
|
|
||||||
|
task.enter(|| {
|
||||||
|
assert_not_ready!(queue);
|
||||||
|
});
|
||||||
|
|
||||||
|
queue.reset_at(&bar, epoch + ms(100));
|
||||||
|
|
||||||
|
advance(timer, ms(100));
|
||||||
|
|
||||||
|
assert!(task.is_notified());
|
||||||
|
let entry = assert_ready!(queue).unwrap().into_inner();
|
||||||
|
assert_eq!(entry, "bar");
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn reset_first_expiring_item_to_expire_later() {
|
||||||
|
mocked(|timer, time| {
|
||||||
|
let mut queue = DelayQueue::new();
|
||||||
|
let mut task = MockTask::new();
|
||||||
|
|
||||||
|
let epoch = time.now();
|
||||||
|
|
||||||
|
let foo = queue.insert_at("foo", epoch + ms(200));
|
||||||
|
let bar = queue.insert_at("bar", epoch + ms(250));
|
||||||
|
|
||||||
|
task.enter(|| {
|
||||||
|
assert_not_ready!(queue);
|
||||||
|
});
|
||||||
|
|
||||||
|
queue.reset_at(&foo, epoch + ms(300));
|
||||||
|
advance(timer, ms(250));
|
||||||
|
|
||||||
|
assert!(task.is_notified());
|
||||||
|
let entry = assert_ready!(queue).unwrap().into_inner();
|
||||||
|
assert_eq!(entry, "bar");
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user