-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The tokio::io::empty
combinator does not participate in coop
#4291
Comments
Reading from If you spawn the |
It occurs to me that |
tokio::io::empty
combinator does not participate in coop
Thanks for reporting this. We should make sure that |
Possibly related/same thing: use std::process::Stdio;
use std::time::Duration;
use tokio::io::AsyncReadExt;
use tokio::process::Command;
use tokio::time::timeout;
#[tokio::main]
async fn main() {
let mut command = Command::new("yes");
command.stdout(Stdio::piped());
let mut spawned = command.spawn().expect("error spawning");
let mut stdout = spawned.stdout.take().expect("no stdout?");
if timeout(Duration::from_millis(1000), async {
loop {
let mut buf = [0u8; 1];
let _ = stdout.read(&mut buf).await;
}
}).await.is_err() {
println!("timedout");
};
} Assuming you have a fast enough yes on your system, then the above also doesn't timeout when it should. |
Reads and buffered reads from a `tokio::io::empty` were always marked as ready. That makes sense, given that there is nothing to wait for. However, doing repeated reads on the `empty` could stall the event loop and prevent other tasks from making progress. This change makes reads on empty objects cooperative. One of every two reads will return `Poll::Pending`, which will give the executor a chance to keep making progress elsewhere. Fixes: tokio-rs#4291
Reads and buffered reads from a `tokio::io::empty` were always marked as ready. That makes sense, given that there is nothing to wait for. However, doing repeated reads on the `empty` could stall the event loop and prevent other tasks from making progress. This change uses tokio's coop system to yield control back to the executor when appropriate. Note that the issue that originally triggered this PR is not fixed yet, because the `timeout` function will not poll the timer after empty::read runs out of budget. A different change will be needed to address that. Refs: tokio-rs#4291
Reads and buffered reads from a `tokio::io::empty` were always marked as ready. That makes sense, given that there is nothing to wait for. However, doing repeated reads on the `empty` could stall the event loop and prevent other tasks from making progress. This change uses tokio's coop system to yield control back to the executor when appropriate. Note that the issue that originally triggered this PR is not fixed yet, because the `timeout` function will not poll the timer after empty::read runs out of budget. A different change will be needed to address that. Refs: #4291
Actually the original issue isn't fixed yet because of #4300 (comment) . I should have updated the PR body. Anyway, I'm working on a PR that finally fixes this problem.
|
Up until now, if the future that we were applying a timeout to consistently depleted the coop budget, the timeout never got a chance to be evaluated. In the next call to `poll`, the underlying future would be polled and it would once again deplete the budget. In those circumstances, timeouts would not be respected. This can be surprising to people, and in fact it was in tokio-rs#4291 . The solution is to make a budget exception with `timeout` if it was the underlying future that depleted the budget.
Up until now, if the future that we were applying a timeout to consistently depleted the coop budget, the timeout never got a chance to be evaluated. In the next call to `poll`, the underlying future would be polled and it would once again deplete the budget. In those circumstances, timeouts would not be respected. This can be surprising to people, and in fact it was in tokio-rs#4291 . The solution is to make a budget exception with `timeout` if it was the underlying future that depleted the budget. Refs: tokio-rs#4291 , tokio-rs#4300
Add coop checks on pipe poll_read and poll_write. Fixes: tokio-rs#4470 Refs: tokio-rs#4291, tokio-rs#4300
Add coop checks on pipe poll_read and poll_write. Fixes: tokio-rs#4470 Refs: tokio-rs#4291, tokio-rs#4300
Add coop checks on pipe poll_read and poll_write. Fixes: tokio-rs#4470 Refs: tokio-rs#4291, tokio-rs#4300
Add coop checks on pipe poll_read and poll_write. Fixes: tokio-rs#4470 Refs: tokio-rs#4291, tokio-rs#4300
Version
List the versions of all
tokio
crates you are using. The easiest way to getthis information is using
cargo tree
subcommand:cargo tree | grep tokio
Platform
The output of
uname -a
(UNIX), or version and 32 or 64-bit (Windows)Linux francis-debian 5.10.0-9-amd64 #1 SMP Debian 5.10.70-1 (2021-09-30) x86_64 GNU/Linux
Description
I tried this code:
I expected to see this happen:
I expected a timeout to occur after 1 second and for the process to exit. Instead it hangs forever.
The text was updated successfully, but these errors were encountered: