From 8cfdcf43f620f467ad3135233528364948d2aa9e Mon Sep 17 00:00:00 2001 From: sharkdp Date: Tue, 1 Jan 2019 22:52:08 +0100 Subject: [PATCH] Lock stdout only once --- src/output.rs | 33 ++++++++++++++++++++------------- src/walk.rs | 15 ++++++++++++--- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/output.rs b/src/output.rs index 0688e7e..ed62f3c 100644 --- a/src/output.rs +++ b/src/output.rs @@ -10,7 +10,7 @@ use crate::exit_codes::ExitCode; use crate::internal::opts::FdOptions; use lscolors::{LsColors, Style}; -use std::io::{self, Write}; +use std::io::{self, StdoutLock, Write}; use std::path::{Component, Path, PathBuf}; use std::process; use std::sync::atomic::{AtomicBool, Ordering}; @@ -28,7 +28,12 @@ fn strip_current_dir<'a>(pathbuf: &'a PathBuf) -> &'a Path { iter.as_path() } -pub fn print_entry(entry: &PathBuf, config: &FdOptions, wants_to_quit: &Arc) { +pub fn print_entry( + stdout: &mut StdoutLock, + entry: &PathBuf, + config: &FdOptions, + wants_to_quit: &Arc, +) { let path = if entry.is_absolute() { entry.as_path() } else { @@ -36,9 +41,9 @@ pub fn print_entry(entry: &PathBuf, config: &FdOptions, wants_to_quit: &Arc io::Result<()> { let default_style = ansi_term::Style::default(); - let stdout = io::stdout(); - let mut handle = stdout.lock(); - // Traverse the path and colorize each component for (component, style) in ls_colors.style_for_path_components(path) { let style = style .map(Style::to_ansi_term_style) .unwrap_or(default_style); - write!(handle, "{}", style.paint(component.to_string_lossy()))?; + write!(stdout, "{}", style.paint(component.to_string_lossy()))?; if wants_to_quit.load(Ordering::Relaxed) { - write!(handle, "\n")?; + write!(stdout, "\n")?; process::exit(ExitCode::KilledBySigint.into()); } } if config.null_separator { - write!(handle, "\0") + write!(stdout, "\0") } else { - writeln!(handle, "") + writeln!(stdout, "") } } -fn print_entry_uncolorized(path: &Path, config: &FdOptions) -> io::Result<()> { +fn print_entry_uncolorized( + stdout: &mut StdoutLock, + path: &Path, + config: &FdOptions, +) -> io::Result<()> { let separator = if config.null_separator { "\0" } else { "\n" }; let path_str = path.to_string_lossy(); - write!(&mut io::stdout(), "{}{}", path_str, separator) + write!(stdout, "{}{}", path_str, separator) } diff --git a/src/walk.rs b/src/walk.rs index efcc4ee..cda2e9d 100644 --- a/src/walk.rs +++ b/src/walk.rs @@ -13,6 +13,7 @@ use crate::internal::{opts::FdOptions, MAX_BUFFER_LENGTH}; use crate::output; use std::error::Error; +use std::io; use std::path::PathBuf; use std::process; use std::sync::atomic::{AtomicBool, Ordering}; @@ -170,6 +171,9 @@ pub fn scan(path_vec: &[PathBuf], pattern: Arc, config: Arc) { .max_buffer_time .unwrap_or_else(|| time::Duration::from_millis(100)); + let stdout = io::stdout(); + let mut stdout = stdout.lock(); + for worker_result in rx { match worker_result { WorkerResult::Entry(value) => { @@ -183,7 +187,12 @@ pub fn scan(path_vec: &[PathBuf], pattern: Arc, config: Arc) { { // Flush the buffer for v in &buffer { - output::print_entry(v, &rx_config, &receiver_wtq); + output::print_entry( + &mut stdout, + v, + &rx_config, + &receiver_wtq, + ); } buffer.clear(); @@ -192,7 +201,7 @@ pub fn scan(path_vec: &[PathBuf], pattern: Arc, config: Arc) { } } ReceiverMode::Streaming => { - output::print_entry(&value, &rx_config, &receiver_wtq); + output::print_entry(&mut stdout, &value, &rx_config, &receiver_wtq); } } } @@ -209,7 +218,7 @@ pub fn scan(path_vec: &[PathBuf], pattern: Arc, config: Arc) { if !buffer.is_empty() { buffer.sort(); for value in buffer { - output::print_entry(&value, &rx_config, &receiver_wtq); + output::print_entry(&mut stdout, &value, &rx_config, &receiver_wtq); } } }