Understanding async executors: futures::local_pool

I'm trying to understand executors and wakers more deeply. I took a look at the single-threaded executor bundled with the futures crate:

My entry point: LocalPool::run https://github.com/rust-lang/futures-rs/blob/master/futures-executor/src/local_pool.rs#L150

I'm wondering if my read of the overall design is correct:

  • Executor starts and polls all futures in the pool of tasks (one pass).
  • At the end of a pass of polling futures, if there's still tasks, the executor parks the thread.
  • When a future is ready to make progress, it wakes up the executor by unparking the thread through a waker.
  • Executor makes another pass of all futures in the pool of tasks.
  • When there's no more tasks in the pool, the executor returns.

I want to understand this properly, since I think that in a more sophisticated executor, there might be separate pools of awake and asleep tasks, and only awake tasks are polled.

So please let me know if I have any misconceptions about how executors work!

1 Like

It sounds about right. Note that in more sophisticated executors such as Tokio, IO is typically implemented by replacing the thread parking with a sleep on an api such as epoll that waits for IO events in a list of IO resources to have any progress, and timers are implemented by putting a timeout on that epoll sleep.

1 Like

Thanks! epoll is something that I'll be looking into soon.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.