comm: hold the stdin lock for the whole duration of the program

Being a single-threaded program, there's no benefit in having comm
obtain a lock every time it needs to read a line. This commit removes
the unnecessary overhead by obtaining a lock at the start of the program
and keeping it for the whole duration of the program.
This commit is contained in:
Andrea Corbellini 2025-10-29 18:19:15 -07:00
parent 514291d86b
commit 35360f75fa

View file

@ -8,7 +8,7 @@
use std::cmp::Ordering;
use std::ffi::OsString;
use std::fs::{File, metadata};
use std::io::{self, BufRead, BufReader, Read, Stdin, stdin};
use std::io::{self, BufRead, BufReader, Read, StdinLock, stdin};
use std::path::Path;
use uucore::error::{FromIo, UResult, USimpleError};
use uucore::format_usage;
@ -55,10 +55,20 @@ struct OrderChecker {
}
enum Input {
Stdin(Stdin),
Stdin(StdinLock<'static>),
FileIn(BufReader<File>),
}
impl Input {
fn stdin() -> Self {
Self::Stdin(stdin().lock())
}
fn from_file(f: File) -> Self {
Self::FileIn(BufReader::new(f))
}
}
struct LineReader {
line_ending: LineEnding,
input: Input,
@ -73,7 +83,7 @@ impl LineReader {
let line_ending = self.line_ending.into();
let result = match &mut self.input {
Input::Stdin(r) => r.lock().read_until(line_ending, buf),
Input::Stdin(r) => r.read_until(line_ending, buf),
Input::FileIn(r) => r.read_until(line_ending, buf),
};
@ -283,16 +293,13 @@ fn comm(a: &mut LineReader, b: &mut LineReader, delim: &str, opts: &ArgMatches)
fn open_file(name: &OsString, line_ending: LineEnding) -> io::Result<LineReader> {
if name == "-" {
Ok(LineReader::new(Input::Stdin(stdin()), line_ending))
Ok(LineReader::new(Input::stdin(), line_ending))
} else {
if metadata(name)?.is_dir() {
return Err(io::Error::other(translate!("comm-error-is-directory")));
}
let f = File::open(name)?;
Ok(LineReader::new(
Input::FileIn(BufReader::new(f)),
line_ending,
))
Ok(LineReader::new(Input::from_file(f), line_ending))
}
}