fix(maestro): poll awaiting-input until leaderless state holds
The pipeline leader exits as soon as both stages are forked, which can beat the surviving stage opening the tty and parking on read — the one- shot assertion then ran against a group with no parked member yet. Poll for the answer, accepting it only while the foreground group is still leaderless so a shell that regained the tty cannot satisfy it. Fixes #113
This commit is contained in:
@@ -189,8 +189,23 @@ fn a_foreground_pipeline_whose_leader_exited_is_still_awaiting_input() {
|
||||
"never observed a foreground group whose leader had exited"
|
||||
);
|
||||
|
||||
assert!(
|
||||
awaiting_input(pane.pane_pid, &pane.tty, &ProcGroups::snapshot()),
|
||||
"a surviving pipeline member still holds the tty"
|
||||
);
|
||||
// The leader can be gone while the surviving stage is still setting up:
|
||||
// `true` exits as soon as both stages are forked, before the reader has
|
||||
// opened the tty and parked. Poll for the answer, but only accept it
|
||||
// while the state this test exists for still holds — otherwise a shell
|
||||
// that regained the terminal would satisfy it vacuously.
|
||||
let deadline = std::time::Instant::now() + Duration::from_secs(5);
|
||||
let mut holds = false;
|
||||
while std::time::Instant::now() < deadline {
|
||||
let groups = ProcGroups::snapshot();
|
||||
let still_leaderless = pgrp_and_tpgid(pane.pane_pid).is_some_and(|(pgrp, tpgid)| {
|
||||
tpgid > 0 && tpgid != pgrp && pgrp_and_tpgid(tpgid).is_none()
|
||||
});
|
||||
if still_leaderless && awaiting_input(pane.pane_pid, &pane.tty, &groups) {
|
||||
holds = true;
|
||||
break;
|
||||
}
|
||||
std::thread::sleep(Duration::from_millis(20));
|
||||
}
|
||||
assert!(holds, "a surviving pipeline member still holds the tty");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user