Skip to content

Commit 3a15482

Browse files
committed
auto merge of #10218 : alexcrichton/rust/stdio-flush-safe, r=cmr
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).
2 parents a300314 + 8f258ab commit 3a15482

File tree

1 file changed

+27
-14
lines changed

1 file changed

+27
-14
lines changed

src/libstd/rt/io/stdio.rs

+27-14
Original file line numberDiff line numberDiff line change
@@ -112,20 +112,17 @@ pub fn stderr() -> StdWriter {
112112
do src(libc::STDERR_FILENO, false) |src| { StdWriter { inner: src } }
113113
}
114114

115-
/// Executes a closure with the local task's handle on stdout. By default, this
116-
/// stream is a buffering stream, so the handled yielded to the given closure
117-
/// can be used to flush the stdout stream (if necessary). The buffering used is
118-
/// line-buffering when stdout is attached to a terminal, and a fixed sized
119-
/// buffer if it is not attached to a terminal.
120-
///
121-
/// Note that handles generated via the `stdout()` function all output to the
122-
/// same stream, and output among all task may be interleaved as a result of
123-
/// this. This is provided to have access to the default stream for `print` and
124-
/// `println` (and the related macros) for this task.
125-
///
126-
/// Also note that logging macros do not use this stream. Using the logging
127-
/// macros will emit output to stderr.
128-
pub fn with_task_stdout(f: &fn(&mut Writer)) {
115+
// Helper to access the local task's stdout handle
116+
//
117+
// Note that this is not a safe function to expose because you can create an
118+
// aliased pointer very easily:
119+
//
120+
// do with_task_stdout |io1| {
121+
// do with_task_stdout |io2| {
122+
// // io1 aliases io2
123+
// }
124+
// }
125+
fn with_task_stdout(f: &fn(&mut Writer)) {
129126
use rt::local::Local;
130127
use rt::task::Task;
131128

@@ -153,6 +150,22 @@ pub fn with_task_stdout(f: &fn(&mut Writer)) {
153150
}
154151
}
155152

153+
/// Flushes the local task's stdout handle.
154+
///
155+
/// By default, this stream is a buffering stream, flushing may be necessary to
156+
/// ensure output is on the terminal screen. The buffering used is
157+
/// line-buffering when stdout is attached to a terminal, and a fixed sized
158+
/// buffer if it is not attached to a terminal.
159+
///
160+
/// Note that logging macros do not use this stream. Using the logging macros
161+
/// will emit output to stderr, and while they are line buffered the log
162+
/// messages are always terminated in a newline (no need to flush).
163+
pub fn flush() {
164+
do with_task_stdout |io| {
165+
io.flush();
166+
}
167+
}
168+
156169
/// Prints a string to the stdout of the current process. No newline is emitted
157170
/// after the string is printed.
158171
pub fn print(s: &str) {

0 commit comments

Comments
 (0)