Hi there, I'm trying to understand wakers and contexts better to be able to tell what the proper solution to the following issue is: https://github.com/Gelbpunkt/tokio-websockets/issues/92
The TL;DR: In the process of poll_next on a stream, we currently call poll_flush(cx) on the underlying I/O to ensure that replies mandated by the protocol (e.g. ping/pong and answering close frames) are at least attempted to be sent out when queued up. The actual result - ready or pending - is ignored. This appears to cause an issue in a weird edge case described in the issue: The user has a fair mutex around the stream and uses one half for writing to the sink and one for reading from it. The writer however gets stuck at some point unless the call to poll_flush(cx) is removed. I can also resolve the issue by creating a new context with a no-op waker that I pass to poll_flush (and also by cloning the waker and using that). tokio-console also complains that the waker has been dropped (on the send task).
My question now is what exactly is going on here. To my understanding, it should be perfectly fine as-is. The poll_next call will try to flush the sink and if that returns pending, it is queued to be woken up again when the sink is supposed to be flushed again. Proceeding to do something else in the same context should be fine, I believe. What exactly is going on here at a runtime level? I went through all the documentation for waker and context, but I just cannot make any sense of this behaviour.