Skip to content

Commit 2cb83fd

Browse files
committed
std: Switch stdout/stderr to buffered by default
Similarly to #12422 which made stdin buffered by default, this commit makes the output streams also buffered by default. Now that buffered writers will flush their contents when they are dropped, I don't believe that there's no reason why the output shouldn't be buffered by default, which is what you want in 90% of cases. As with stdin, there are new stdout_raw() and stderr_raw() functions to get unbuffered streams to stdout/stderr.
1 parent 1ee94a1 commit 2cb83fd

File tree

9 files changed

+41
-21
lines changed

9 files changed

+41
-21
lines changed

src/librustc/lib.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,7 @@ pub fn run_compiler(args: &[~str]) {
297297
match input {
298298
d::FileInput(ref ifile) => {
299299
let mut stdout = io::stdout();
300-
d::list_metadata(sess, &(*ifile),
301-
&mut stdout as &mut io::Writer).unwrap();
300+
d::list_metadata(sess, &(*ifile), &mut stdout).unwrap();
302301
}
303302
d::StrInput(_) => {
304303
d::early_error("can not list metadata for stdin");

src/libstd/fmt/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -654,8 +654,8 @@ uniform_fn_call_workaround! {
654654
/// use std::fmt;
655655
/// use std::io;
656656
///
657-
/// let w = &mut io::stdout() as &mut io::Writer;
658-
/// format_args!(|args| { fmt::write(w, args); }, "Hello, {}!", "world");
657+
/// let mut w = io::stdout();
658+
/// format_args!(|args| { fmt::write(&mut w, args); }, "Hello, {}!", "world");
659659
/// ```
660660
pub fn write(output: &mut io::Writer, args: &Arguments) -> Result {
661661
unsafe { write_unsafe(output, args.fmt, args.args) }

src/libstd/io/stdio.rs

+29-5
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@ fn src<T>(fd: libc::c_int, readable: bool, f: |StdSource| -> T) -> T {
9090
/// buffered access is not desired, the `stdin_raw` function is provided to
9191
/// provided unbuffered access to stdin.
9292
///
93+
/// Care should be taken when creating multiple handles to the stdin of a
94+
/// process. Beause this is a buffered reader by default, it's possible for
95+
/// pending input to be unconsumed in one reader and unavailable to other
96+
/// readers. It is recommended that only one handle at a time is created for the
97+
/// stdin of a process.
98+
///
9399
/// See `stdout()` for more notes about this function.
94100
pub fn stdin() -> BufferedReader<StdReader> {
95101
BufferedReader::new(stdin_raw())
@@ -104,20 +110,38 @@ pub fn stdin_raw() -> StdReader {
104110
src(libc::STDIN_FILENO, true, |src| StdReader { inner: src })
105111
}
106112

107-
/// Creates a new non-blocking handle to the stdout of the current process.
113+
/// Creates a line-buffered handle to the stdout of the current process.
108114
///
109115
/// Note that this is a fairly expensive operation in that at least one memory
110116
/// allocation is performed. Additionally, this must be called from a runtime
111117
/// task context because the stream returned will be a non-blocking object using
112118
/// the local scheduler to perform the I/O.
113-
pub fn stdout() -> StdWriter {
119+
///
120+
/// Care should be taken when creating multiple handles to an output stream for
121+
/// a single process. While usage is still safe, the output may be surprising if
122+
/// no synchronization is performed to ensure a sane output.
123+
pub fn stdout() -> LineBufferedWriter<StdWriter> {
124+
LineBufferedWriter::new(stdout_raw())
125+
}
126+
127+
/// Creates an unbuffered handle to the stdout of the current process
128+
///
129+
/// See notes in `stdout()` for more information.
130+
pub fn stdout_raw() -> StdWriter {
114131
src(libc::STDOUT_FILENO, false, |src| StdWriter { inner: src })
115132
}
116133

117-
/// Creates a new non-blocking handle to the stderr of the current process.
134+
/// Creates a line-buffered handle to the stderr of the current process.
118135
///
119136
/// See `stdout()` for notes about this function.
120-
pub fn stderr() -> StdWriter {
137+
pub fn stderr() -> LineBufferedWriter<StdWriter> {
138+
LineBufferedWriter::new(stderr_raw())
139+
}
140+
141+
/// Creates an unbuffered handle to the stderr of the current process
142+
///
143+
/// See notes in `stdout()` for more information.
144+
pub fn stderr_raw() -> StdWriter {
121145
src(libc::STDERR_FILENO, false, |src| StdWriter { inner: src })
122146
}
123147

@@ -182,7 +206,7 @@ fn with_task_stdout(f: |&mut Writer| -> IoResult<()> ) {
182206
Local::put(task);
183207

184208
if my_stdout.is_none() {
185-
my_stdout = Some(~LineBufferedWriter::new(stdout()) as ~Writer);
209+
my_stdout = Some(~stdout() as ~Writer);
186210
}
187211
let ret = f(*my_stdout.get_mut_ref());
188212

src/libstd/logging.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -166,9 +166,7 @@ pub fn log(level: u32, args: &fmt::Arguments) {
166166
};
167167

168168
if logger.is_none() {
169-
logger = Some(~DefaultLogger {
170-
handle: LineBufferedWriter::new(io::stderr()),
171-
} as ~Logger);
169+
logger = Some(~DefaultLogger { handle: io::stderr(), } as ~Logger);
172170
}
173171
logger.get_mut_ref().log(level, args);
174172

src/libsyntax/diagnostic.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,8 @@ enum Destination {
227227
impl EmitterWriter {
228228
pub fn stderr() -> EmitterWriter {
229229
let stderr = io::stderr();
230-
if stderr.isatty() {
231-
let dst = match term::Terminal::new(stderr) {
230+
if stderr.get_ref().isatty() {
231+
let dst = match term::Terminal::new(stderr.unwrap()) {
232232
Ok(t) => Terminal(t),
233233
Err(..) => Raw(~io::stderr()),
234234
};

src/libtest/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -415,8 +415,8 @@ impl<T: Writer> ConsoleTestState<T> {
415415
Some(ref path) => Some(try!(File::create(path))),
416416
None => None
417417
};
418-
let out = match term::Terminal::new(io::stdout()) {
419-
Err(_) => Raw(io::stdout()),
418+
let out = match term::Terminal::new(io::stdio::stdout_raw()) {
419+
Err(_) => Raw(io::stdio::stdout_raw()),
420420
Ok(t) => Pretty(t)
421421
};
422422
Ok(ConsoleTestState {

src/test/bench/shootout-fasta-redux.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// except according to those terms.
1010

1111
use std::cmp::min;
12-
use std::io::{stdout, BufferedWriter, IoResult};
12+
use std::io::{stdout, IoResult};
1313
use std::os;
1414
use std::vec::bytes::copy_memory;
1515
use std::vec;
@@ -183,7 +183,7 @@ fn main() {
183183
5
184184
};
185185

186-
let mut out = BufferedWriter::new(stdout());
186+
let mut out = stdout();
187187

188188
out.write_line(">ONE Homo sapiens alu").unwrap();
189189
{

src/test/bench/shootout-fasta.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,6 @@ fn main() {
117117
let mut file = BufferedWriter::new(File::create(&Path::new("./shootout-fasta.data")));
118118
run(&mut file);
119119
} else {
120-
run(&mut BufferedWriter::new(io::stdout()));
120+
run(&mut io::stdout());
121121
}
122122
}

src/test/bench/shootout-mandelbrot.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
// except according to those terms.
1010

1111
use std::io;
12-
use std::io::BufferedWriter;
1312

1413
struct DummyWriter;
1514
impl Writer for DummyWriter {
@@ -27,7 +26,7 @@ fn main() {
2726
(1000, ~DummyWriter as ~Writer)
2827
} else {
2928
(from_str(args[1]).unwrap(),
30-
~BufferedWriter::new(std::io::stdout()) as ~Writer)
29+
~std::io::stdout() as ~Writer)
3130
};
3231
let h = w;
3332
let mut byte_acc = 0u8;

0 commit comments

Comments
 (0)