aboutsummaryrefslogtreecommitdiff
path: root/embassy-executor/src/raw/mod.rs
diff options
context:
space:
mode:
authorDániel Buga <[email protected]>2024-12-17 18:05:48 +0100
committerDániel Buga <[email protected]>2024-12-17 18:07:06 +0100
commit8fd08b1e97533c7526bb4937770060d18bb37410 (patch)
tree3e30a41e0d630f6b472bd85a4407f600ca07410a /embassy-executor/src/raw/mod.rs
parentedb8f21a741358f7c80b744f008f1e5acc77b429 (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.rs17
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 }