Calling an async function in a blocking manner (no_std)

So I have an async function defined like this:

pub async fn identify(&mut self, nsid: u32, cntid: u16, cns: u8, nvmsetid: u16, uuid: u8) -> Result<IdentifyResponse, queues::Status>

And I'd like to call it but in a non-async context. I know that runtimes have a block_on method but I have absolutely no idea how to implement one myself. I've tried calling it by wrapping it in an async block but, of course, that won't ever be run, and the compiler complains that it returns a result (I'm guessing the future) that I need to use. But I can't utilize the future in a synchronous context in any way that I know of without using some really weird hackery. So is there an easier way of doing this that doesn't consume ridiculously large amounts of LoC and that doesn't require me to dig in obscure parts of the core library? All my searches have yielded results that just look incredibly messy to use.
I've looked at generators, but I don't think generators will work in this situation.

An async function returns an object that implements the Future trait. The way that a runtime works is that it will call the Future::poll method on the future. If the poll method returns Poll::Pending, it means that the future is not able to complete now because it is waiting for some operation (this could be e.g. a timer).

The way that the runtime knows when to call poll again after a Poll::Pending is through the Context parameter. Before calling poll, the runtime has constructed a Waker object, which it gives to the future through that context. When the future is ready to continue running, the wake method is called on the Waker, and the runtime has customized this method such that the runtime is told about the call.

Note that to call poll, you must first pin the future. This can be done either through the Box::pin function, a macro like futures::pin_mut! or tokio::pin!, or using the unsafe function Pin::new_unchecked. Creating a Waker also involves unsafe, but it can be made safe through the ArcWake trait from the futures crate.

The Tokio tutorial contains an example implementation of a runtime: Async in depth.

1 Like