futures-rs icon indicating copy to clipboard operation
futures-rs copied to clipboard

Clarify semantics of calling different poll_* methods from different tasks

Open alecmocatta opened this issue 4 years ago • 2 comments

How many Wakers should items implementing say AsyncRead and AsyncWrite have to store? At least some libs1 store two – a "read waker" and a "write waker". The former is set during poll_read and poll_read_vectored, and the latter during poll_write, poll_write_vectored, poll_flush and poll_close. Is this sufficient?

What about an application that poll_writes from one task, but, for example, poll_flushes from another, background, task? There's a race between tasks to be the last to set the "write waker", and the losing task may never be able to be woken.

This would be fine, but it's somewhat surprising and it's not totally obvious from the documentation.


1. For example it seems e.g. tokio::net::TcpStream and tokio-tungstenite do this

alecmocatta avatar Dec 20 '20 09:12 alecmocatta

There's a race between tasks to be the last to set the "write waker", and the losing task may never be able to be woken.

Yeah, it can actually happen, but as far as I know, there is no known AsyncRead/AsyncWrite implementation that actually supports any number of concurrent I/O operations.

See also #2139

taiki-e avatar Dec 22 '20 09:12 taiki-e

There's a race between tasks to be the last to set the "write waker", and the losing task may never be able to be woken.

Yeah, it can actually happen, but as far as I know, there is no known AsyncRead/AsyncWrite implementation that actually supports any number of concurrent I/O operations.

FYI: tokio has docs that clarify this (https://github.com/tokio-rs/tokio/pull/3310)

Note that on multiple calls to poll_peek, poll_read or poll_read_ready, only the Waker from the Context passed to the most recent call is scheduled to receive a wakeup. (However, poll_write retains a second, independent waker.)

taiki-e avatar Jan 01 '21 05:01 taiki-e