about summary refs log tree commit diff
path: root/src/libstd/rt/logging.rs
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2013-10-17 17:04:51 -0700
committerAlex Crichton <alex@alexcrichton.com>2013-10-24 14:21:57 -0700
commit4eb53360541baf3e6df36dc0f0766bc7c1c9f8be (patch)
tree0b78ce834f9df44297595d66b38883831811b99f /src/libstd/rt/logging.rs
parent4ce71eaca34526d0e3ee1ebf0658d2a20d388ef2 (diff)
Move as much I/O as possible off of native::io
When uv's TTY I/O is used for the stdio streams, the file descriptors are put
into a non-blocking mode. This means that other concurrent writes to the same
stream can fail with EAGAIN or EWOULDBLOCK. By all I/O to event-loop I/O, we
avoid this error.

There is one location which cannot move, which is the runtime's dumb_println
function. This was implemented to handle the EAGAIN and EWOULDBLOCK errors and
simply retry again and again.
Diffstat (limited to 'src/libstd/rt/logging.rs')
-rw-r--r--src/libstd/rt/logging.rs20
1 files changed, 15 insertions, 5 deletions
diff --git a/src/libstd/rt/logging.rs b/src/libstd/rt/logging.rs
index 660d1cd4359..31650ede700 100644
--- a/src/libstd/rt/logging.rs
+++ b/src/libstd/rt/logging.rs
@@ -12,6 +12,7 @@ use fmt;
 use from_str::from_str;
 use libc::exit;
 use option::{Some, None, Option};
+use rt::io;
 use rt::crate_map::{ModEntry, CrateMap, iter_crate_map, get_crate_map};
 use str::StrSlice;
 use u32;
@@ -166,14 +167,23 @@ pub trait Logger {
     fn log(&mut self, args: &fmt::Arguments);
 }
 
-pub struct StdErrLogger;
+/// This logger emits output to the stderr of the process, and contains a lazily
+/// initialized event-loop driven handle to the stream.
+pub struct StdErrLogger {
+    priv handle: Option<io::stdio::StdWriter>,
+}
+
+impl StdErrLogger {
+    pub fn new() -> StdErrLogger { StdErrLogger { handle: None } }
+}
 
 impl Logger for StdErrLogger {
     fn log(&mut self, args: &fmt::Arguments) {
-        // FIXME(#6846): this should not call the blocking version of println,
-        //               or at least the default loggers for tasks shouldn't do
-        //               that
-        ::rt::util::dumb_println(args);
+        // First time logging? Get a handle to the stderr of this process.
+        if self.handle.is_none() {
+            self.handle = Some(io::stderr());
+        }
+        fmt::writeln(self.handle.get_mut_ref() as &mut io::Writer, args);
     }
 }