From 3d3915844a020c2f9ab5e03bdacd64c0f0d1aa38 Mon Sep 17 00:00:00 2001 From: Matt Green Date: Tue, 25 Oct 2016 05:15:08 -0400 Subject: [PATCH] Improve runner API --- src/main.rs | 19 +++++++------- src/runner.rs | 69 ++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 59 insertions(+), 29 deletions(-) diff --git a/src/main.rs b/src/main.rs index 1b53b67..6e09aaa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -118,17 +118,17 @@ fn main() { } let cmd = args.cmd; - let mut runner = Runner::new(); + let (mut runner, child_rx) = Runner::new(); + let mut child_process = None; if args.run_initially { if args.clear_screen { runner.clear_screen(); } - runner.run_command(&cmd, vec![]); + child_process = runner.run_command(&cmd, vec![]); } - let mut child_wait_rx = None; while !interrupt_handler::interrupt_requested() { match wait(&rx, &interrupt_rx, &filter) { Some(paths) => { @@ -136,12 +136,13 @@ fn main() { .map(|p| p.to_str().unwrap()) .collect(); - if args.restart { - runner.kill(); - } + if let Some(mut child) = child_process { + if args.restart { + debug!("Killing child process"); + child.kill(); + } - debug!("Waiting for process to exit..."); - if let Some(child_rx) = child_wait_rx { + debug!("Waiting for process to exit..."); select! { _ = child_rx.recv() => {}, _ = interrupt_rx.recv() => break @@ -152,7 +153,7 @@ fn main() { runner.clear_screen(); } - child_wait_rx = Some(runner.run_command(&cmd, updated)); + child_process = runner.run_command(&cmd, updated); } None => { // interrupted diff --git a/src/runner.rs b/src/runner.rs index e3b2771..34a0382 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -1,19 +1,21 @@ use std::process::Command; -use std::sync::mpsc::{channel, Receiver}; +use std::sync::mpsc::{channel, Receiver, Sender}; use threadpool::ThreadPool; pub struct Runner { pool: ThreadPool, - process: Option, + tx: Sender<()>, } impl Runner { - pub fn new() -> Runner { - Runner { + pub fn new() -> (Runner, Receiver<()>) { + let (tx, rx) = channel(); + (Runner { pool: ThreadPool::new(1), - process: None, - } + tx: tx, + }, + rx) } #[cfg(target_family = "windows")] @@ -26,30 +28,53 @@ impl Runner { let _ = Command::new("clear").status(); } - pub fn kill(&mut self) { - if let Some(ref mut process) = self.process { - process.kill(); - } - } + pub fn run_command(&mut self, + cmd: &str, + updated_paths: Vec<&str>) + -> Option { + let child = Process::new(cmd, updated_paths); - pub fn run_command(&mut self, cmd: &str, updated_paths: Vec<&str>) -> Receiver<()> { - let (tx, rx) = channel(); - - if let Some(mut process) = platform::Process::new(cmd, updated_paths) { - self.process = Some(process.clone()); + if let Some(ref process) = child { + let tx = self.tx.clone(); + let mut p = process.as_platform_process(); self.pool.execute(move || { - process.wait(); + p.wait(); let _ = tx.send(()); }); } - rx + child } } -impl Drop for Runner { +pub struct Process { + process: platform::Process +} + +impl Process { + pub fn new(cmd: &str, updated_paths: Vec<&str>) -> Option { + platform::Process::new(cmd, updated_paths).and_then(|p| { + Some(Process { process: p }) + }) + } + + fn as_platform_process(&self) -> platform::Process { + self.process.clone() + } + + pub fn kill(&mut self) { + self.process.kill(); + } + + #[allow(dead_code)] + pub fn wait(&mut self) { + self.process.wait(); + } +} + +impl Drop for Process { fn drop(&mut self) { self.kill(); } @@ -85,7 +110,11 @@ mod platform { .ok(); match c { - Some(process) => Some(Process { child_pid: process.id() as i32 }), + Some(process) => { + Some(Process { + child_pid: process.id() as i32, + }) + } None => None, } }