Delete timer state when the future that's awaiting it gets dropped

This commit is contained in:
Antonio Scandurra 2022-03-02 10:08:38 +01:00
parent 8b7a9367fa
commit be7a4770fb

View file

@ -16,7 +16,8 @@ use std::{
use crate::{
platform::{self, Dispatcher},
util, MutableAppContext,
util::{self, post_inc},
MutableAppContext,
};
pub enum Foreground {
@ -69,7 +70,8 @@ struct DeterministicState {
forbid_parking: bool,
block_on_ticks: std::ops::RangeInclusive<usize>,
now: std::time::Instant,
pending_timers: Vec<(std::time::Instant, postage::barrier::Sender)>,
next_timer_id: usize,
pending_timers: Vec<(usize, std::time::Instant, postage::barrier::Sender)>,
waiting_backtrace: Option<backtrace::Backtrace>,
}
@ -99,6 +101,7 @@ impl Deterministic {
forbid_parking: false,
block_on_ticks: 0..=1000,
now: std::time::Instant::now(),
next_timer_id: Default::default(),
pending_timers: Default::default(),
waiting_backtrace: None,
})),
@ -426,11 +429,31 @@ impl Foreground {
use postage::prelude::Stream as _;
let (tx, mut rx) = postage::barrier::channel();
let timer_id;
{
let mut state = executor.state.lock();
let wakeup_at = state.now + duration;
state.pending_timers.push((wakeup_at, tx));
timer_id = post_inc(&mut state.next_timer_id);
state.pending_timers.push((timer_id, wakeup_at, tx));
}
struct DropTimer<'a>(usize, &'a Foreground);
impl<'a> Drop for DropTimer<'a> {
fn drop(&mut self) {
match self.1 {
Foreground::Deterministic { executor, .. } => {
executor
.state
.lock()
.pending_timers
.retain(|(timer_id, _, _)| *timer_id != self.0);
}
_ => unreachable!(),
}
}
}
let _guard = DropTimer(timer_id, self);
rx.recv().await;
}
_ => {
@ -451,7 +474,7 @@ impl Foreground {
let mut pending_timers = mem::take(&mut state.pending_timers);
drop(state);
pending_timers.retain(|(wakeup, _)| *wakeup > now);
pending_timers.retain(|(_, wakeup, _)| *wakeup > now);
executor.state.lock().pending_timers.extend(pending_timers);
}
_ => panic!("this method can only be called on a deterministic executor"),