From 15501132916dfbc24f23b619e6d5408f258fc0d9 Mon Sep 17 00:00:00 2001 From: Jonas Maier <> Date: Wed, 11 Mar 2026 12:30:07 +0100 Subject: can wait for threads & processes with a timeout now --- src/run/mod.rs | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) (limited to 'src/run/mod.rs') diff --git a/src/run/mod.rs b/src/run/mod.rs index 5666574..6af1717 100644 --- a/src/run/mod.rs +++ b/src/run/mod.rs @@ -2,11 +2,11 @@ use std::collections::HashMap; use std::fs::File; use std::io::{PipeReader, PipeWriter}; use std::path::PathBuf; -use std::process::Child; use std::sync::{Arc, Mutex}; use std::thread::JoinHandle; use crate::parse::{self, Ast, PostExpansion, PreExpansion}; +use crate::wait::{ChildWaiter, ThreadWaiter}; use crate::*; mod builtin; @@ -147,18 +147,24 @@ impl Write for Output { } enum SpawnedCmd { - Builtin(JoinHandle>), - Fun(JoinHandle>), - Child(Child), + Builtin(ThreadWaiter>), + Fun(ThreadWaiter>), + Child(ChildWaiter), SpawnError(io::Error), + Joined(Result<(), ExecError>), } impl SpawnedCmd { fn join(self) -> Result<(), ExecError> { match self { - SpawnedCmd::Builtin(handle) => handle.join().map_err(|_| ExecError::Panic)??, - SpawnedCmd::Fun(handle) => handle.join().map_err(|_| ExecError::Panic)??, - SpawnedCmd::Child(mut child) => { + SpawnedCmd::Builtin(handle) => { + handle.into_inner().join().map_err(|_| ExecError::Panic)?? + } + SpawnedCmd::Fun(handle) => { + handle.into_inner().join().map_err(|_| ExecError::Panic)?? + } + SpawnedCmd::Child(child) => { + let mut child = child.into_inner(); let exit_code = child.wait()?; match exit_code.code() { Some(0) => (), @@ -167,9 +173,24 @@ impl SpawnedCmd { } } SpawnedCmd::SpawnError(err) => Err(err)?, + SpawnedCmd::Joined(res) => res?, } Ok(()) } + + /// returns whether the spawned command is already joined + fn join_timeout(&mut self, timeout_ms: u16) -> bool { + match self { + SpawnedCmd::Builtin(tw) => tw.try_join(timeout_ms), + SpawnedCmd::Fun(tw) => tw.try_join(timeout_ms), + SpawnedCmd::Child(child) => match child.wait(timeout_ms) { + Ok(None) => false, + _ => true, + }, + SpawnedCmd::SpawnError(_) => true, + SpawnedCmd::Joined(_) => true, + } + } } impl Executor { @@ -192,7 +213,7 @@ impl Executor { CommandKind::Builtin(builtin) => { builtin.special(self.se.clone(), &args[1..]); let cloned_session = self.se.clone(); - let handle = std::thread::spawn(move || { + let handle = wait::spawn(move || { builtin.io(cloned_session, &args[1..], &mut stdin, &mut stdout) }); SpawnedCmd::Builtin(handle) @@ -201,7 +222,7 @@ impl Executor { let mut this = self.clone(); this.args = Some(args); - let handle = std::thread::spawn(move || { + let handle = wait::spawn(move || { let ast = ast.expand(&mut this)?; this.execute(ast, stdin, stdout)?; Ok(()) @@ -221,7 +242,7 @@ impl Executor { crate::export_fun::prepare_command(self.se.clone(), &mut command); match command.spawn() { - Ok(c) => SpawnedCmd::Child(c), + Ok(c) => SpawnedCmd::Child(ChildWaiter::new(c).unwrap()), Err(e) => SpawnedCmd::SpawnError(e), } } -- cgit v1.2.3