Make sure an exited task does not get stuck in a timer queue

This commit is contained in:
Dániel Buga 2024-12-13 21:45:52 +01:00
parent 2f2e2c6031
commit 5c4983236c
No known key found for this signature in database
2 changed files with 18 additions and 0 deletions

View File

@ -192,7 +192,17 @@ impl<F: Future + 'static> TaskStorage<F> {
match future.poll(&mut cx) {
Poll::Ready(_) => {
this.future.drop_in_place();
// Mark this task to be timer queued, to prevent re-queueing it.
this.raw.state.timer_enqueue();
// Now mark the task as not spawned, so that
// - it can be spawned again once it has been removed from the timer queue
// - it can not be timer-queued again
this.raw.state.despawn();
// Schedule the task by hand in the past, so it runs immediately.
unsafe { _embassy_time_schedule_wake(0, &waker) }
}
Poll::Pending => {}
}
@ -211,6 +221,10 @@ impl<F: Future + 'static> TaskStorage<F> {
}
}
extern "Rust" {
fn _embassy_time_schedule_wake(at: u64, waker: &core::task::Waker);
}
/// An uninitialized [`TaskStorage`].
pub struct AvailableTask<F: Future + 'static> {
task: &'static TaskStorage<F>,

View File

@ -150,3 +150,7 @@ fn executor_task_cfg_args() {
let (_, _, _) = (a, b, c);
}
}
// We need this for the test to compile, even though we don't want to use timers at the moment.
#[no_mangle]
fn _embassy_time_schedule_wake(_at: u64, _waker: &core::task::Waker) {}