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
Stdin can block shutdown #2466
Comments
Why doesn't tokio just epoll stdin directly in this case? stdin is a pipe and can therefore be used with Here's the example in #2318, using use std::convert::TryFrom;
use tokio::io::AsyncReadExt;
#[tokio::main]
async fn main() {
//let mut stdin = tokio::io::stdin(); // replaced with:
let mut stdin = tokio_fd::AsyncFd::try_from(libc::STDIN_FILENO).unwrap();
let mut buffer = [0; 8];
let duration = std::time::Duration::from_secs(3);
let timeout = tokio::time::sleep(duration);
tokio::select! {
_ = stdin.read(&mut buffer) => println!("reading done"),
_ = timeout => println!("timeout!"),
}
println!("the end")
} With this change the program no longer blocks when shutting down. |
|
It's not just pipes but e.g. ptys too. I'd generalize it to the following observation: stdio file descriptors often exist in multiple non-cooperating processes. Changing the properties of a file descriptor in one process affects all other processes. One linux-only workaround, at least for pipes, is to reopen the file descriptor through For ptys, a workaround is to reopen |
Overall tokio makes this little echo example a lot simpler/clean. I ran into trouble with stdin reading blocking exit of the client due to tokio-rs/tokio#2466, but shoving it on to a thread worked wonders.
Types such as
Stdin
andStdout
internally use blocking IO to read from the streams. This means that shutdown of the runtime can be blocked on threads with pending operations of this kind.See #2318 as an example of when this happens.
The text was updated successfully, but these errors were encountered: