From 8f258ab532eebce705b5eb27cc8635400992ca54 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 31 Oct 2013 22:09:48 -0700 Subject: [PATCH] Provide a sound method of flushing stdout The previous method was unsound because you could very easily create two mutable pointers which alias the same location (not sound behavior). This hides the function which does so and then exports an explicit flush() function (with documentation about how it works). --- src/libstd/rt/io/stdio.rs | 41 ++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/src/libstd/rt/io/stdio.rs b/src/libstd/rt/io/stdio.rs index eeffc20a336d5..1284ab736560f 100644 --- a/src/libstd/rt/io/stdio.rs +++ b/src/libstd/rt/io/stdio.rs @@ -112,20 +112,17 @@ pub fn stderr() -> StdWriter { do src(libc::STDERR_FILENO, false) |src| { StdWriter { inner: src } } } -/// Executes a closure with the local task's handle on stdout. By default, this -/// stream is a buffering stream, so the handled yielded to the given closure -/// can be used to flush the stdout stream (if necessary). The buffering used is -/// line-buffering when stdout is attached to a terminal, and a fixed sized -/// buffer if it is not attached to a terminal. -/// -/// Note that handles generated via the `stdout()` function all output to the -/// same stream, and output among all task may be interleaved as a result of -/// this. This is provided to have access to the default stream for `print` and -/// `println` (and the related macros) for this task. -/// -/// Also note that logging macros do not use this stream. Using the logging -/// macros will emit output to stderr. -pub fn with_task_stdout(f: &fn(&mut Writer)) { +// Helper to access the local task's stdout handle +// +// Note that this is not a safe function to expose because you can create an +// aliased pointer very easily: +// +// do with_task_stdout |io1| { +// do with_task_stdout |io2| { +// // io1 aliases io2 +// } +// } +fn with_task_stdout(f: &fn(&mut Writer)) { use rt::local::Local; use rt::task::Task; @@ -153,6 +150,22 @@ pub fn with_task_stdout(f: &fn(&mut Writer)) { } } +/// Flushes the local task's stdout handle. +/// +/// By default, this stream is a buffering stream, flushing may be necessary to +/// ensure output is on the terminal screen. The buffering used is +/// line-buffering when stdout is attached to a terminal, and a fixed sized +/// buffer if it is not attached to a terminal. +/// +/// Note that logging macros do not use this stream. Using the logging macros +/// will emit output to stderr, and while they are line buffered the log +/// messages are always terminated in a newline (no need to flush). +pub fn flush() { + do with_task_stdout |io| { + io.flush(); + } +} + /// Prints a string to the stdout of the current process. No newline is emitted /// after the string is printed. pub fn print(s: &str) {