From 30e1e3a13dc19c47afc517d1178e1dbf5b401596 Mon Sep 17 00:00:00 2001 From: syn Date: Sun, 9 Feb 2020 19:17:57 +0300 Subject: timeout'ed waiter for process --- src/wait/mod.rs | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 src/wait/mod.rs (limited to 'src/wait/mod.rs') diff --git a/src/wait/mod.rs b/src/wait/mod.rs new file mode 100644 index 0000000..9761f08 --- /dev/null +++ b/src/wait/mod.rs @@ -0,0 +1,81 @@ +use nix::libc::{self, c_int}; +use nix::{ + errno::Errno, + sys::wait::WaitStatus, + unistd::Pid +}; +use std::time::{ Instant, Duration }; +use std::process::Child; +use std::thread; +use std::sync::mpsc; + +mod error; +mod rusage_ffi; +pub use rusage_ffi::Rusage; + +pub use error::WaitError; + +#[derive(Debug)] +pub struct WaitInfo { + pub status: WaitStatus, + pub usage: Rusage, + pub wall_time: Duration +} + + +fn wait4_pid( + pid: Pid, + chan: mpsc::Sender>, + timer: Instant +) { + let mut status: c_int = 0; + let mut usg: libc::rusage; + let wait_ret; + + unsafe { + usg = std::mem::zeroed(); + wait_ret = libc::wait4(pid.as_raw(), &mut status, 0 as c_int, &mut usg); + } + + #[allow(unused_must_use)] { + chan.send(match wait_ret { + -1 => Err(nix::Error::Sys(Errno::last())), + _ => WaitStatus::from_raw(pid, status).map(|nix_status| { + WaitInfo { + status: nix_status, + usage: usg.into(), + wall_time: timer.elapsed() + } + } + ) + }); + }; +} + + +pub fn wait_child( + mut child: Child, + timeout: Duration, + timer: Instant +) -> Result { + let pid = Pid::from_raw(child.id() as i32); + let (send, recv) = mpsc::channel(); + + let thr = thread::spawn(move || wait4_pid(pid, send, timer)); + + match recv.recv_timeout(timeout) { + Ok(Ok(usg)) => Ok(usg), + Ok(Err(err)) => Err(err.into()), + Err(mpsc::RecvTimeoutError::Timeout) => { + drop(recv); + drop(thr); + + #[allow(unused_must_use)] { + child.kill(); + } + + Err(WaitError::TimedOut(timeout)) + }, + Err(mpsc::RecvTimeoutError::Disconnected) => unreachable!() + } +} -- cgit v1.2.1-18-gbd029