diff options
| author | Dániel Buga <[email protected]> | 2024-12-17 18:05:48 +0100 |
|---|---|---|
| committer | Dániel Buga <[email protected]> | 2024-12-17 18:07:06 +0100 |
| commit | 8fd08b1e97533c7526bb4937770060d18bb37410 (patch) | |
| tree | 3e30a41e0d630f6b472bd85a4407f600ca07410a /embassy-executor/src/raw/mod.rs | |
| parent | edb8f21a741358f7c80b744f008f1e5acc77b429 (diff) | |
Swap poll_fn to allow polling exited tasks
Diffstat (limited to 'embassy-executor/src/raw/mod.rs')
| -rw-r--r-- | embassy-executor/src/raw/mod.rs | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs index c79fdae60..242e9c365 100644 --- a/embassy-executor/src/raw/mod.rs +++ b/embassy-executor/src/raw/mod.rs | |||
| @@ -202,16 +202,29 @@ impl<F: Future + 'static> TaskStorage<F> { | |||
| 202 | } | 202 | } |
| 203 | } | 203 | } |
| 204 | 204 | ||
| 205 | unsafe fn poll_to_despawn(p: TaskRef) { | ||
| 206 | // The task's future has already been dropped, we just mark it as `!SPAWNED`. | ||
| 207 | let this = &*p.as_ptr().cast::<TaskStorage<F>>(); | ||
| 208 | this.raw.state.despawn(); | ||
| 209 | } | ||
| 210 | |||
| 205 | unsafe fn poll(p: TaskRef) { | 211 | unsafe fn poll(p: TaskRef) { |
| 206 | let this = &*(p.as_ptr() as *const TaskStorage<F>); | 212 | let this = &*p.as_ptr().cast::<TaskStorage<F>>(); |
| 207 | 213 | ||
| 208 | let future = Pin::new_unchecked(this.future.as_mut()); | 214 | let future = Pin::new_unchecked(this.future.as_mut()); |
| 209 | let waker = waker::from_task(p); | 215 | let waker = waker::from_task(p); |
| 210 | let mut cx = Context::from_waker(&waker); | 216 | let mut cx = Context::from_waker(&waker); |
| 211 | match future.poll(&mut cx) { | 217 | match future.poll(&mut cx) { |
| 212 | Poll::Ready(_) => { | 218 | Poll::Ready(_) => { |
| 219 | waker.wake_by_ref(); | ||
| 220 | |||
| 221 | // As the future has finished and this function will not be called | ||
| 222 | // again, we can safely drop the future here. | ||
| 213 | this.future.drop_in_place(); | 223 | this.future.drop_in_place(); |
| 214 | this.raw.state.despawn(); | 224 | |
| 225 | // We replace the poll_fn with a despawn function, so that the task is cleaned up | ||
| 226 | // when the executor polls it next. | ||
| 227 | this.raw.poll_fn.set(Some(Self::poll_to_despawn)); | ||
| 215 | } | 228 | } |
| 216 | Poll::Pending => {} | 229 | Poll::Pending => {} |
| 217 | } | 230 | } |
