Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to make Future counter?

I’m willing to impl a simple Future counter, but smth goes decidedly wrong about it. Without any use of Context the following programme would just block forever;

use std::future::Future;
use std::task::{Poll, Context};
use std::pin::Pin;
use futures::executor::block_on;

struct MyStruct {
    counter: u32
}

impl Future for MyStruct {
    type Output = String;

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        if self.counter == 5 {
            Poll::Ready(self.counter.to_string())
        } else {
            unsafe {
                Pin::get_unchecked_mut(self).counter += 1;
            }
//            cx.waker().wake();
            Poll::Pending
        }
    }
}

fn main() {
    let ms = MyStruct{counter: 0};
    block_on(ms);
}

I imagine that I have to postpone somehow a call of Waker, but it’s not that straightforward. So I wonder, how to wake it in the most simple form?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

You can call .wake_by_ref(). Waking the waker will tell the executor that is handling the Future to be .poll()‘d again:

impl Future for MyStruct {
    type Output = String;

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        if self.counter == 5 {
            Poll::Ready(self.counter.to_string())
        } else {
            unsafe {
                Pin::get_unchecked_mut(self).counter += 1;
            }
            cx.waker().wake_by_ref();
            Poll::Pending
        }
    }
}

So your implementation will always ask to be immediately re-polled. I’ll note that this is logically no different than simply returning Poll::Ready("5".to_string()) on the first invocation since there’s no asynchronous work being done here. Because of that, there’s no reason for it to be a Future at all.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading