-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Tracking issue for Child::try_wait #38903
Comments
If this does not block, there’s not waiting involved? |
One problem I'm grappling with right now is how to wait on a child (in one thread) while leaving open the option of killing it later (from another thread) if it hasn't exited yet. Right now the
If it's true that |
@oconnor663 what you're trying to do is inherently race-prone on Unix and It does indeed sound like |
Golang added (private) support for |
Hmm, rust-lang/libc#489 seems to have included Mac support though. I'll play with it. (Interesting timing!) |
Thinking more about how I'm going to expose a similar API in duct. I think I'm going to opt for if let Some(status) = foo.try_wait()? {
...
} else {
...
} instead of like this match foo.try_wait() {
Ok(status) => {
...
}
Err(err) if err.kind() == io::ErrorKind::WouldBlock => {
...
}
Err(err) => return Err(err),
} The non-blocking Name-wise, I agree with @SimonSapin that the term "try_wait" is kind of confusing, though I guess it's consistent with what libc calls everything, and with the |
@oconnor663 good point about using Also yeah the name is mostly inspired by mutexes and other nonblocking/opportunistic operations which are prefixed with |
@alexcrichton would you be interested in a PR that tried out the |
Oh oops I thought that it already did that actually. Sure if you want to send a PR sounds good to me! |
We
|
This is much nicer for callers who want to short-circuit real I/O errors with `?`, because they can write this if let Some(status) = foo.try_wait()? { ... } else { ... } instead of this match foo.try_wait() { Ok(status) => { ... } Err(err) if err.kind() == io::ErrorKind::WouldBlock => { ... } Err(err) => return Err(err), } The original design of `try_wait` was patterned after the `Read` and `Write` traits, which support both blocking and non-blocking implementations in a single API. But since `try_wait` is never blocking, it makes sense to optimize for the non-blocking case. Tracking issue: rust-lang#38903
make Child::try_wait return io::Result<Option<ExitStatus>> This is much nicer for callers who want to short-circuit real I/O errors with `?`, because they can write this if let Some(status) = foo.try_wait()? { ... } else { ... } instead of this match foo.try_wait() { Ok(status) => { ... } Err(err) if err.kind() == io::ErrorKind::WouldBlock => { ... } Err(err) => return Err(err), } The original design of `try_wait` was patterned after the `Read` and `Write` traits, which support both blocking and non-blocking implementations in a single API. But since `try_wait` is never blocking, it makes sense to optimize for the non-blocking case. Tracking issue: rust-lang#38903
make Child::try_wait return io::Result<Option<ExitStatus>> This is much nicer for callers who want to short-circuit real I/O errors with `?`, because they can write this if let Some(status) = foo.try_wait()? { ... } else { ... } instead of this match foo.try_wait() { Ok(status) => { ... } Err(err) if err.kind() == io::ErrorKind::WouldBlock => { ... } Err(err) => return Err(err), } The original design of `try_wait` was patterned after the `Read` and `Write` traits, which support both blocking and non-blocking implementations in a single API. But since `try_wait` is never blocking, it makes sense to optimize for the non-blocking case. Tracking issue: rust-lang#38903
make Child::try_wait return io::Result<Option<ExitStatus>> This is much nicer for callers who want to short-circuit real I/O errors with `?`, because they can write this if let Some(status) = foo.try_wait()? { ... } else { ... } instead of this match foo.try_wait() { Ok(status) => { ... } Err(err) if err.kind() == io::ErrorKind::WouldBlock => { ... } Err(err) => return Err(err), } The original design of `try_wait` was patterned after the `Read` and `Write` traits, which support both blocking and non-blocking implementations in a single API. But since `try_wait` is never blocking, it makes sense to optimize for the non-blocking case. Tracking issue: rust-lang#38903
Any updates on this issue? Right now this function leaves a hole in the lockscreen for Way Cooler where the lock screen program could have failed but we can't clean the input locks / stored PID properly because there's no way to check the status of the program without blocking. |
@Timidger is there any chance you could use the |
@oconnor663 Thanks, it looks like that crate will work. Would be nice for this to be in the stable standard library thought :-/. Until this stabilizes I'll try to use that then. |
Aha and that reminds me! @rfcbot fcp merge |
Team member @alexcrichton has proposed to merge this. The next step is review by the rest of the tagged teams: No concerns currently listed. Once these reviewers reach consensus, this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
This is much nicer for callers who want to short-circuit real I/O errors with `?`, because they can write this if let Some(status) = foo.try_wait()? { ... } else { ... } instead of this match foo.try_wait() { Ok(status) => { ... } Err(err) if err.kind() == io::ErrorKind::WouldBlock => { ... } Err(err) => return Err(err), } The original design of `try_wait` was patterned after the `Read` and `Write` traits, which support both blocking and non-blocking implementations in a single API. But since `try_wait` is never blocking, it makes sense to optimize for the non-blocking case. Tracking issue: rust-lang/rust#38903
make Child::try_wait return io::Result<Option<ExitStatus>> This is much nicer for callers who want to short-circuit real I/O errors with `?`, because they can write this if let Some(status) = foo.try_wait()? { ... } else { ... } instead of this match foo.try_wait() { Ok(status) => { ... } Err(err) if err.kind() == io::ErrorKind::WouldBlock => { ... } Err(err) => return Err(err), } The original design of `try_wait` was patterned after the `Read` and `Write` traits, which support both blocking and non-blocking implementations in a single API. But since `try_wait` is never blocking, it makes sense to optimize for the non-blocking case. Tracking issue: rust-lang/rust#38903
🔔 This is now entering its final comment period, as per the review above. 🔔 |
@alexcrichton, what actually happens at the end of the FCP? |
@oconnor663 the method is stabilized and will land in the next release or the one after that depending on the timing. |
The final comment period is now complete. |
Closes rust-lang#38863 Closes rust-lang#38980 Closes rust-lang#38903 Closes rust-lang#36648
Stabilize library features for 1.18.0 Closes #38863 Closes #38980 Closes #38903 Closes #36648 r? @alexcrichton @rust-lang/libs
Closes rust-lang#38863 Closes rust-lang#38980 Closes rust-lang#38903 Closes rust-lang#36648
Introduced in #38866 this is a tracking issue for the
Child::try_wait
method.This method attempts to wait for a child and collect its status but does not block. Questions for stabilization include:
io::Result<T>
vsio::Result<Option<T>>
)The text was updated successfully, but these errors were encountered: