Understanding the local_pool executor

Per this post, the OP described his understanding of how futures::local_pool works. Thanks to his insights, which helped me building up an basic understanding of it.

However, when I got more seriously digging into the code, I realized that the implementation of futures::local_pool is actually more sophisticated than what the OP described - it is actually a very comprehensive implementation of a single-threaded executor not just for toy projects!

The implementation is not just polling all the (top-level) futures in a loop - the actual LocalPool::pool is of type FuturesUnordered, whose Stream::poll_next method (StreamExt::poll_next_unpin) interally does the magic of replacing the outer waker context (which simply unparks the thread) with an internal task waker context, which contains a waker from Task<Fut>, whose ArcWake::wake_by_ref method queues the future to the FuturesUnordered::ready_to_run_queue, and then invokes the outter wake to unpark the thread to process the ready futures - so essentially, the local_pool executor only polls the ready futures, if any, at every top level LocalPool::poll_pool method.

As to the IO/timers wakeup side, I think it's the "reactor" part of the executor that the local_pool executor doesn't (and probably wouldn't) address, which basically just uses the whatever waker reference to wakeup the future - though I'm pretty sure that the waker reference would be the Task::wake_by_refas mentioned above (actually queues the ready future to the ready_to_run_futures queue.

Hopefully, this understanding of local_pool executor is correct?

1 Like

Yes, your understanding is correct.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.