Lock stdout only once

This commit is contained in:
sharkdp 2019-01-01 22:52:08 +01:00 committed by David Peter
parent 8c197d2866
commit 8cfdcf43f6
2 changed files with 32 additions and 16 deletions

View file

@ -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<AtomicBool>) {
pub fn print_entry(
stdout: &mut StdoutLock,
entry: &PathBuf,
config: &FdOptions,
wants_to_quit: &Arc<AtomicBool>,
) {
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<Atom
};
let r = if let Some(ref ls_colors) = config.ls_colors {
print_entry_colorized(path, config, ls_colors, &wants_to_quit)
print_entry_colorized(stdout, path, config, ls_colors, &wants_to_quit)
} else {
print_entry_uncolorized(path, config)
print_entry_uncolorized(stdout, path, config)
};
if r.is_err() {
@ -48,6 +53,7 @@ pub fn print_entry(entry: &PathBuf, config: &FdOptions, wants_to_quit: &Arc<Atom
}
fn print_entry_colorized(
stdout: &mut StdoutLock,
path: &Path,
config: &FdOptions,
ls_colors: &LsColors,
@ -55,33 +61,34 @@ fn print_entry_colorized(
) -> 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)
}

View file

@ -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<Regex>, config: Arc<FdOptions>) {
.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<Regex>, config: Arc<FdOptions>) {
{
// 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<Regex>, config: Arc<FdOptions>) {
}
}
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<Regex>, config: Arc<FdOptions>) {
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);
}
}
}