What is the use of RawWaker,RawWakerVtble?

In Asyn/await rust poll method takes Contex type argument.Contex type wrapper around waker type and it is wrapper around RawWaker type.

why need of 1.RawWaker type 2.RawWakervtble type

And how it works

Edit: First of all note, that you don’t need to use poll directly when working with async fn and Future. In particular Waker and moreso RawWaker are only really necessary when implementing your own async primitives / executor / combinators. So as an average Rust programmer you don’t usually need to care about these implementation details at all. Also it might be helpful to learn how async and Futures are used first, in case you haven’t already, before getting into their inner workings.

On the other hand, it of course makes sense to look at these details to get a deeper understanding to what Futures and asynchronous programming in Rust really is/are, so I don't (Edit: missed the "don't") want to discourage you from learning if you’re curious.


A Waker is pretty similar to an Arc<dyn Wake + Sync + Send>, where the Wake trait is

pub trait Wake {
    pub fn wake(self: Arc<Self>);

    pub fn wake_by_ref(self: &Arc<Self>);
}

Ignoring the fact that a Wake trait like this is not actually object safe.

Context contains a reference to a Waker.


As to why the Wakers exist in the first place, IMO THIS VIDEO does a great explanation of how futures etc. work (internally) in general. This is not a tutorial, so as noted above, it might be helpful and more motivating to first learn about how to use async and Futures, and crates such as tokio from some other sources.

It is a bit older and still works with the old futures::executor::Notify trait which is a bit different

pub trait Notify: Send + Sync {
    fn notify(&self, id: usize);

    fn clone_id(&self, id: usize) -> usize;
    fn drop_id(&self, id: usize);
}

ignoring everything but the main method notify vs wake_by_ref, the only significant difference is the id parameter, but that’s not too important; AFAICT you might need fewer distinct notifiers than wakers due to the id argument bening another possibility for distinguishing them.

The rest corresponds like this:

  • NotifyHandle is like Waker
  • it uses *mut dyn UnsafeNotify instead of a more explicit pointer+vtable struct
  • the Future trait at the time had
    fn poll(&mut self) -> Poll<Self::Item, Self::Error>
    
    so there was always a possible custom error type and no pinning or wakers/notifiers passed explicitly, instead a NotifyHandle could be passed through a thread-local variable using the with_notify function. Similar to how other executor-specific things are still passed using thread-locals today so that e.g. most functions from the tokio crate only work in the “context” of a tokio executor.

Goddammit, docs.rs just went down, so I can’t look up any more things about tokio or the futures crate right now. Got of the information that I wanted so far, anyways. Yay, it’s back up.

2 Likes

Thank you