libasync: wrap_waker()
This commit is contained in:
parent
25e80f63f9
commit
8bc721826c
|
@ -30,6 +30,12 @@ static VTABLE: RawWakerVTable = {
|
||||||
RawWakerVTable::new(clone, wake, wake_by_ref, drop)
|
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
|
/// A single-threaded executor
|
||||||
///
|
///
|
||||||
/// This is a singleton
|
/// This is a singleton
|
||||||
|
@ -67,8 +73,7 @@ impl Executor {
|
||||||
|
|
||||||
pin_mut!(f);
|
pin_mut!(f);
|
||||||
let ready = AtomicBool::new(true);
|
let ready = AtomicBool::new(true);
|
||||||
let waker =
|
let waker = wrap_waker(&ready);
|
||||||
unsafe { Waker::from_raw(RawWaker::new(&ready as *const _ as *const _, &VTABLE)) };
|
|
||||||
let val = loop {
|
let val = loop {
|
||||||
// advance the main task
|
// advance the main task
|
||||||
if ready.load(Ordering::Relaxed) {
|
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`
|
// we are about to service the task so switch the `ready` flag to `false`
|
||||||
task.ready.store(false, Ordering::Relaxed);
|
task.ready.store(false, Ordering::Relaxed);
|
||||||
|
|
||||||
// NOTE we never deallocate tasks so `&ready` is always pointing to
|
let waker = wrap_waker(&task.ready);
|
||||||
// allocated memory (`&'static AtomicBool`)
|
|
||||||
let waker = unsafe {
|
|
||||||
Waker::from_raw(RawWaker::new(&task.ready as *const _ as *const _, &VTABLE))
|
|
||||||
};
|
|
||||||
let mut cx = Context::from_waker(&waker);
|
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();
|
let ready = task.f.as_mut().poll(&mut cx).is_ready();
|
||||||
if ready {
|
if ready {
|
||||||
// Task is finished, do not requeue
|
// Task is finished, do not requeue
|
||||||
|
|
Loading…
Reference in New Issue