From 394e967b5fa2d6b19068ff34bef0ecbd1591c490 Mon Sep 17 00:00:00 2001 From: Max Triano Date: Tue, 23 Jun 2020 11:29:04 -0400 Subject: [PATCH] No buffering cmd output when running on 1 thread --- src/exec/command.rs | 35 ++++++++++++++--------------------- src/exec/job.rs | 8 +++++--- src/exec/mod.rs | 8 ++++---- src/walk.rs | 10 +++++++--- 4 files changed, 30 insertions(+), 31 deletions(-) diff --git a/src/exec/command.rs b/src/exec/command.rs index 99e4640..1baa15d 100644 --- a/src/exec/command.rs +++ b/src/exec/command.rs @@ -7,26 +7,19 @@ use crate::error::print_error; use crate::exit_codes::ExitCode; /// Executes a command. -pub fn execute_command(mut cmd: Command, out_perm: &Mutex<()>) -> ExitCode { +pub fn execute_command(mut cmd: Command, out_perm: &Mutex<()>, is_multithread: bool) -> ExitCode { + let output; // Spawn the supplied command. - /* let output = cmd.output(); */ - // This sort of works: - let child = cmd.spawn().expect("failed to wait on child"); - let output = child - .wait_with_output() - .expect("failed to wait on child"); - ExitCode::Success - /* let child_handle = cmd.spawn(); - match child_handle { - Ok(output) => { - let exit_code = output.wait(); - } - Err() => { - - } - } */ + if is_multithread { + output = cmd.output(); + } else { + // This sort of works: + let child = cmd.spawn().expect("Failed to execute command"); + output = child.wait_with_output(); + } + // Then wait for the command to exit, if it was spawned. - /* match output { + match output { Ok(output) => { // While this lock is active, this thread will be the only thread allowed // to write its outputs. @@ -35,8 +28,8 @@ pub fn execute_command(mut cmd: Command, out_perm: &Mutex<()>) -> ExitCode { let stdout = io::stdout(); let stderr = io::stderr(); - //let _ = stdout.lock().write_all(&output.stdout); - //let _ = stderr.lock().write_all(&output.stderr); + let _ = stdout.lock().write_all(&output.stdout); + let _ = stderr.lock().write_all(&output.stderr); if output.status.code() == Some(0) { ExitCode::Success @@ -52,5 +45,5 @@ pub fn execute_command(mut cmd: Command, out_perm: &Mutex<()>) -> ExitCode { print_error(format!("Problem while executing command: {}", why)); ExitCode::GeneralError } - } */ + } } diff --git a/src/exec/job.rs b/src/exec/job.rs index eef042a..9b27516 100644 --- a/src/exec/job.rs +++ b/src/exec/job.rs @@ -16,6 +16,7 @@ pub fn job( cmd: Arc, out_perm: Arc>, show_filesystem_errors: bool, + is_multithread: bool, ) -> ExitCode { let mut results: Vec = Vec::new(); loop { @@ -34,11 +35,11 @@ pub fn job( } Err(_) => break, }; - + // Drop the lock so that other threads can read from the receiver. drop(lock); // Generate a command, execute it and store its exit code. - results.push(cmd.generate_and_execute(&value, Arc::clone(&out_perm))) + results.push(cmd.generate_and_execute(&value, Arc::clone(&out_perm), is_multithread)) } // Returns error in case of any error. merge_exitcodes(&results) @@ -48,6 +49,7 @@ pub fn batch( rx: Receiver, cmd: &CommandTemplate, show_filesystem_errors: bool, + is_multithread: bool, ) -> ExitCode { let paths = rx.iter().filter_map(|value| match value { WorkerResult::Entry(val) => Some(val), @@ -58,5 +60,5 @@ pub fn batch( None } }); - cmd.generate_and_execute_batch(paths) + cmd.generate_and_execute_batch(paths, is_multithread) } diff --git a/src/exec/mod.rs b/src/exec/mod.rs index f24c0e3..9a3d6df 100644 --- a/src/exec/mod.rs +++ b/src/exec/mod.rs @@ -139,7 +139,7 @@ impl CommandTemplate { /// /// Using the internal `args` field, and a supplied `input` variable, a `Command` will be /// build. Once all arguments have been processed, the command is executed. - pub fn generate_and_execute(&self, input: &Path, out_perm: Arc>) -> ExitCode { + pub fn generate_and_execute(&self, input: &Path, out_perm: Arc>, is_multithread: bool) -> ExitCode { let input = strip_current_dir(input); let mut cmd = Command::new(self.args[0].generate(&input, self.path_separator.as_deref())); @@ -147,14 +147,14 @@ impl CommandTemplate { cmd.arg(arg.generate(&input, self.path_separator.as_deref())); } - execute_command(cmd, &out_perm) + execute_command(cmd, &out_perm, is_multithread) } pub fn in_batch_mode(&self) -> bool { self.mode == ExecutionMode::Batch } - pub fn generate_and_execute_batch(&self, paths: I) -> ExitCode + pub fn generate_and_execute_batch(&self, paths: I, is_multithread: bool) -> ExitCode where I: Iterator, { @@ -182,7 +182,7 @@ impl CommandTemplate { } if has_path { - execute_command(cmd, &Mutex::new(())) + execute_command(cmd, &Mutex::new(()), is_multithread) } else { ExitCode::Success } diff --git a/src/walk.rs b/src/walk.rs index e2966b3..9da49aa 100644 --- a/src/walk.rs +++ b/src/walk.rs @@ -170,12 +170,16 @@ fn spawn_receiver( let show_filesystem_errors = config.show_filesystem_errors; let threads = config.threads; - + let is_multithread: bool = if threads > 1 { + true + } else { + false + }; thread::spawn(move || { // This will be set to `Some` if the `--exec` argument was supplied. if let Some(ref cmd) = config.command { if cmd.in_batch_mode() { - exec::batch(rx, cmd, show_filesystem_errors) + exec::batch(rx, cmd, show_filesystem_errors, is_multithread) } else { let shared_rx = Arc::new(Mutex::new(rx)); @@ -190,7 +194,7 @@ fn spawn_receiver( // Spawn a job thread that will listen for and execute inputs. let handle = - thread::spawn(move || exec::job(rx, cmd, out_perm, show_filesystem_errors)); + thread::spawn(move || exec::job(rx, cmd, out_perm, show_filesystem_errors, is_multithread)); // Push the handle of the spawned thread into the vector for later joining. handles.push(handle);