From 8bc721826cff8de4cc21f5ee8c63eb3470419b38 Mon Sep 17 00:00:00 2001 From: Astro Date: Tue, 31 Mar 2020 18:55:03 +0200 Subject: [PATCH] libasync: wrap_waker() --- libasync/src/executor.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/libasync/src/executor.rs b/libasync/src/executor.rs index 2de395c..4fbd57e 100644 --- a/libasync/src/executor.rs +++ b/libasync/src/executor.rs @@ -30,6 +30,12 @@ static VTABLE: RawWakerVTable = { RawWakerVTable::new(clone, wake, wake_by_ref, drop) }; +/// ready should not move as long as this waker references it. That is +/// the reason for keeping Tasks in a pinned box. +fn wrap_waker(ready: &AtomicBool) -> Waker { + unsafe { Waker::from_raw(RawWaker::new(ready as *const _ as *const _, &VTABLE)) } +} + /// A single-threaded executor /// /// This is a singleton @@ -67,8 +73,7 @@ impl Executor { pin_mut!(f); let ready = AtomicBool::new(true); - let waker = - unsafe { Waker::from_raw(RawWaker::new(&ready as *const _ as *const _, &VTABLE)) }; + let waker = wrap_waker(&ready); let val = loop { // advance the main task if ready.load(Ordering::Relaxed) { @@ -94,14 +99,8 @@ impl Executor { // we are about to service the task so switch the `ready` flag to `false` task.ready.store(false, Ordering::Relaxed); - // NOTE we never deallocate tasks so `&ready` is always pointing to - // allocated memory (`&'static AtomicBool`) - let waker = unsafe { - Waker::from_raw(RawWaker::new(&task.ready as *const _ as *const _, &VTABLE)) - }; + let waker = wrap_waker(&task.ready); let mut cx = Context::from_waker(&waker); - // this points into a `static` memory so it's already pinned - // println!("run task"); let ready = task.f.as_mut().poll(&mut cx).is_ready(); if ready { // Task is finished, do not requeue