How to call "wake()" to queue that future again for execution from the same thread in future

From the async book, i understood that we must call "wake()" to again queue that future for execution on the executor, it had an example of calling "wake()" by passing waker to another thread, but i wanna know how this is achieved from single thread, is there some sort of system call involved? How does one actually get notified when some packet as arrived on the socket when the application is using just single thread in async code

E. g. tokio is building on top of the mio crate (mio - Rust) which ultimately uses API provided by the operating system (such as epoll on Linux) in order to be able to wait on and react to multiple concurrent IO sources on a single thread. I don't know the implementation details but I suppose there's some way of associating IO operations in the main mio::Poll data structure to the relevant waker that needs to be called upon completion. Then there needs to be one main event loop that calls the relevant wakers whenever IO events come in. For fully single threaded operation, I assume the event loop and future execution loop need to be somehow interleaved.

1 Like

For more information, this search result turned out to be an interesting read Tokio internals: Understanding Rust's asynchronous I/O framework from the bottom up : Caffeinated Bitstream I particularly liked the flow chart of the event loop.

It does work with an outdated version of the Future trait that didn't include any context/waker argument in the poll method yet, so it does the same kind of thing by passing it via a thread-local and the operation is not called "wake" but "notify". With that in mind, it should be possible to make sense of how most or all the mentioned API relates to what's available in their up to date counterparts. Also the information about the implementation details of either Tokio or Mio might be outdated, but even if it is, at least it explains the basic workings of some possible way of doing these things.

1 Like

Yeah, basically Tokio has a big table of all pending IO operations with a mapping from the resource id (file descriptor on linux) to the waker that should be notified when the operation is able to complete. When you try to make an operation and it fails with "can't do that right now", it is added to that table, and every so often between polling tasks, Tokio will ask the OS which resources have become ready, and notify the wakers of the relevant tasks.

2 Likes

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.