diff options
| author | Dániel Buga <[email protected]> | 2024-12-13 21:45:52 +0100 |
|---|---|---|
| committer | Dániel Buga <[email protected]> | 2024-12-15 18:50:00 +0100 |
| commit | 5c4983236c2e68b6ba2ce325ed77ec39466fc3b6 (patch) | |
| tree | 9e3e2bc1f374d494fb6f83ad523654ae2a52b2b9 | |
| parent | 2f2e2c6031a1abaecdac5ed2febe109e647fe6fd (diff) | |
Make sure an exited task does not get stuck in a timer queue
| -rw-r--r-- | embassy-executor/src/raw/mod.rs | 14 | ||||
| -rw-r--r-- | embassy-executor/tests/test.rs | 4 |
2 files changed, 18 insertions, 0 deletions
diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs index 2feaab155..b825fa6c2 100644 --- a/embassy-executor/src/raw/mod.rs +++ b/embassy-executor/src/raw/mod.rs | |||
| @@ -192,7 +192,17 @@ impl<F: Future + 'static> TaskStorage<F> { | |||
| 192 | match future.poll(&mut cx) { | 192 | match future.poll(&mut cx) { |
| 193 | Poll::Ready(_) => { | 193 | Poll::Ready(_) => { |
| 194 | this.future.drop_in_place(); | 194 | this.future.drop_in_place(); |
| 195 | |||
| 196 | // Mark this task to be timer queued, to prevent re-queueing it. | ||
| 197 | this.raw.state.timer_enqueue(); | ||
| 198 | |||
| 199 | // Now mark the task as not spawned, so that | ||
| 200 | // - it can be spawned again once it has been removed from the timer queue | ||
| 201 | // - it can not be timer-queued again | ||
| 195 | this.raw.state.despawn(); | 202 | this.raw.state.despawn(); |
| 203 | |||
| 204 | // Schedule the task by hand in the past, so it runs immediately. | ||
| 205 | unsafe { _embassy_time_schedule_wake(0, &waker) } | ||
| 196 | } | 206 | } |
| 197 | Poll::Pending => {} | 207 | Poll::Pending => {} |
| 198 | } | 208 | } |
| @@ -211,6 +221,10 @@ impl<F: Future + 'static> TaskStorage<F> { | |||
| 211 | } | 221 | } |
| 212 | } | 222 | } |
| 213 | 223 | ||
| 224 | extern "Rust" { | ||
| 225 | fn _embassy_time_schedule_wake(at: u64, waker: &core::task::Waker); | ||
| 226 | } | ||
| 227 | |||
| 214 | /// An uninitialized [`TaskStorage`]. | 228 | /// An uninitialized [`TaskStorage`]. |
| 215 | pub struct AvailableTask<F: Future + 'static> { | 229 | pub struct AvailableTask<F: Future + 'static> { |
| 216 | task: &'static TaskStorage<F>, | 230 | task: &'static TaskStorage<F>, |
diff --git a/embassy-executor/tests/test.rs b/embassy-executor/tests/test.rs index 0ce1f1891..992ab3da9 100644 --- a/embassy-executor/tests/test.rs +++ b/embassy-executor/tests/test.rs | |||
| @@ -150,3 +150,7 @@ fn executor_task_cfg_args() { | |||
| 150 | let (_, _, _) = (a, b, c); | 150 | let (_, _, _) = (a, b, c); |
| 151 | } | 151 | } |
| 152 | } | 152 | } |
| 153 | |||
| 154 | // We need this for the test to compile, even though we don't want to use timers at the moment. | ||
| 155 | #[no_mangle] | ||
| 156 | fn _embassy_time_schedule_wake(_at: u64, _waker: &core::task::Waker) {} | ||
