Async deadlock in Stream implementation

Hi, I want to get a futures::Stream for the output of a std::process::Command.
But my implementation so far blocks after the first call to poll_next() (which returns Poll::Pending).

My (limited) understanding of the async world is that the executor (tokio::main) should retry calling poll_next().

Here is my code:

Any ideas on

  1. how I could achieve what I want, and
  2. why exactly my code example deadlocks?

The docs for Stream could be a little clearer imo, you're missing this part of Stream::poll_next:

registering the current task for wakeup if the value is not yet available

The docs for AsyncRead::poll_read are more explicit about what you need to do:

If no data is available for reading, the method returns Poll::Pending and arranges for the current task (via cx.waker().wake_by_ref() ) to receive a notification when the object becomes readable or is closed.

Adding

cx.waker().wake_by_ref();

before you return Poll::Pending makes your code complete running. You can check the async book for more info about wakers and other async stuff.

You can't really implement it this way. You should be using tokio::process instead.

1 Like

Oh, I looked into tokio::process::Command, and apparently didn't look far enough. I was surprised that the "output()" Future returns a Vec instead of something streaming the result. Following the documentation further to tokio::process::ChildStdout, I see the poll_read() method I was missing.
Thanks!

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.