Merge nucleic/sleek-thistle-egret-fyej into dev
This commit is contained in:
@@ -17,6 +17,9 @@ pub struct ChildProcess {
|
||||
pid: Option<sys::process::ProcessId>,
|
||||
/// If available, the process group ID of the child.
|
||||
pgid: Option<sys::process::ProcessId>,
|
||||
// nash: gate token issued by `Gate::on_exec` for this command, reported
|
||||
// back via `Gate::on_exit` when the process completes.
|
||||
pub(crate) gate_token: Option<u64>,
|
||||
}
|
||||
|
||||
impl ChildProcess {
|
||||
@@ -30,6 +33,7 @@ impl ChildProcess {
|
||||
exec_future: Box::pin(child.wait_with_output()),
|
||||
pid,
|
||||
pgid,
|
||||
gate_token: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +58,15 @@ impl ChildProcess {
|
||||
loop {
|
||||
tokio::select! {
|
||||
output = &mut self.exec_future => {
|
||||
break Ok(ProcessWaitResult::Completed(output?))
|
||||
let output = output?;
|
||||
// nash: report process completion to the gate exactly once.
|
||||
if let Some(token) = self.gate_token.take() {
|
||||
crate::gate::gate().on_exit(
|
||||
token,
|
||||
crate::gate::ExecEnd { exit_code: exit_code_of(&output.status) },
|
||||
);
|
||||
}
|
||||
break Ok(ProcessWaitResult::Completed(output))
|
||||
},
|
||||
_ = sigtstp.recv() => {
|
||||
break Ok(ProcessWaitResult::Stopped)
|
||||
@@ -75,12 +87,39 @@ impl ChildProcess {
|
||||
|
||||
pub(crate) fn poll(&mut self) -> Option<Result<std::process::Output, error::Error>> {
|
||||
let checkable_future = &mut self.exec_future;
|
||||
checkable_future
|
||||
let result: Option<Result<std::process::Output, error::Error>> = checkable_future
|
||||
.now_or_never()
|
||||
.map(|result| result.map_err(Into::into))
|
||||
.map(|result| result.map_err(Into::into));
|
||||
// nash: completion can also be observed via poll (e.g. job checks).
|
||||
if let Some(Ok(output)) = &result {
|
||||
if let Some(token) = self.gate_token.take() {
|
||||
crate::gate::gate().on_exit(
|
||||
token,
|
||||
crate::gate::ExecEnd {
|
||||
exit_code: exit_code_of(&output.status),
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
// nash: numeric exit code for gate reporting (128+signal for signal deaths).
|
||||
fn exit_code_of(status: &std::process::ExitStatus) -> i32 {
|
||||
if let Some(code) = status.code() {
|
||||
return code;
|
||||
}
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use std::os::unix::process::ExitStatusExt;
|
||||
if let Some(signal) = status.signal() {
|
||||
return 128 + signal;
|
||||
}
|
||||
}
|
||||
1
|
||||
}
|
||||
|
||||
/// Represents the result of waiting for an executing process.
|
||||
pub enum ProcessWaitResult {
|
||||
/// The process completed.
|
||||
|
||||
Reference in New Issue
Block a user