about summary refs log tree commit diff
path: root/src/libstd/rt
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-11-13 19:46:18 -0800
committerbors <bors@rust-lang.org>2013-11-13 19:46:18 -0800
commit58b5c618cfa4b5bec9dd0a27f2ecac07365febe7 (patch)
treef5345fc82faac047e765a45ce289f1d73f3e98d0 /src/libstd/rt
parent8a3b35f68a32c3d0111d12b058d24852b024f1b3 (diff)
parent9bcf557589a385d163c6d543ede82953b09e072f (diff)
downloadrust-58b5c618cfa4b5bec9dd0a27f2ecac07365febe7.tar.gz
rust-58b5c618cfa4b5bec9dd0a27f2ecac07365febe7.zip
auto merge of #10457 : alexcrichton/rust/native-io, r=brson
This commit re-organizes the io::native module slightly in order to have a
working implementation of rtio::IoFactory which uses native implementations. The
goal is to seamlessly multiplex among libuv/native implementations wherever
necessary.

Right now most of the native I/O is unimplemented, but we have existing bindings
for file descriptors and processes which have been hooked up. What this means is
that you can now invoke println!() from libstd with no local task, no local
scheduler, and even without libuv.

There's still plenty of work to do on the native I/O factory, but this is the
first steps into making it an official portion of the standard library. I don't
expect anyone to reach into io::native directly, but rather only std::io
primitives will be used. Each std::io interface seamlessly falls back onto the
native I/O implementation if the local scheduler doesn't have a libuv one
(hurray trait ojects!)
Diffstat (limited to 'src/libstd/rt')
-rw-r--r--src/libstd/rt/basic.rs10
-rw-r--r--src/libstd/rt/rtio.rs26
-rw-r--r--src/libstd/rt/util.rs24
3 files changed, 29 insertions, 31 deletions
diff --git a/src/libstd/rt/basic.rs b/src/libstd/rt/basic.rs
index a8f762c4c8f..42ecbf5dc78 100644
--- a/src/libstd/rt/basic.rs
+++ b/src/libstd/rt/basic.rs
@@ -18,6 +18,7 @@ use cast;
 use rt::rtio::{EventLoop, IoFactory, RemoteCallback, PausibleIdleCallback,
                Callback};
 use unstable::sync::Exclusive;
+use io::native;
 use util;
 
 /// This is the only exported function from this module.
@@ -30,7 +31,8 @@ struct BasicLoop {
     idle: Option<*mut BasicPausible>, // only one is allowed
     remotes: ~[(uint, ~Callback)],
     next_remote: uint,
-    messages: Exclusive<~[Message]>
+    messages: Exclusive<~[Message]>,
+    io: ~IoFactory,
 }
 
 enum Message { RunRemote(uint), RemoveRemote(uint) }
@@ -54,6 +56,7 @@ impl BasicLoop {
             next_remote: 0,
             remotes: ~[],
             messages: Exclusive::new(~[]),
+            io: ~native::IoFactory as ~IoFactory,
         }
     }
 
@@ -167,8 +170,9 @@ impl EventLoop for BasicLoop {
         ~BasicRemote::new(self.messages.clone(), id) as ~RemoteCallback
     }
 
-    /// This has no bindings for local I/O
-    fn io<'a>(&'a mut self, _: &fn(&'a mut IoFactory)) {}
+    fn io<'a>(&'a mut self, f: &fn(&'a mut IoFactory)) {
+        f(self.io)
+    }
 }
 
 struct BasicRemote {
diff --git a/src/libstd/rt/rtio.rs b/src/libstd/rt/rtio.rs
index ca1fd413a56..35fb8baa6ce 100644
--- a/src/libstd/rt/rtio.rs
+++ b/src/libstd/rt/rtio.rs
@@ -78,20 +78,28 @@ pub enum CloseBehavior {
 pub fn with_local_io<T>(f: &fn(&mut IoFactory) -> Option<T>) -> Option<T> {
     use rt::sched::Scheduler;
     use rt::local::Local;
-    use io::{io_error, standard_error, IoUnavailable};
+    use io::native;
 
     unsafe {
-        let sched: *mut Scheduler = Local::unsafe_borrow();
-        let mut io = None;
-        (*sched).event_loop.io(|i| io = Some(i));
-        match io {
-            Some(io) => f(io),
-            None => {
-                io_error::cond.raise(standard_error(IoUnavailable));
-                None
+        // First, attempt to use the local scheduler's I/O services
+        let sched: Option<*mut Scheduler> = Local::try_unsafe_borrow();
+        match sched {
+            Some(sched) => {
+                let mut io = None;
+                (*sched).event_loop.io(|i| io = Some(i));
+                match io {
+                    Some(io) => return f(io),
+                    None => {}
+                }
             }
+            None => {}
         }
     }
+
+    // If we don't have a scheduler or the scheduler doesn't have I/O services,
+    // then fall back to the native I/O services.
+    let mut io = native::IoFactory;
+    f(&mut io as &mut IoFactory)
 }
 
 pub trait IoFactory {
diff --git a/src/libstd/rt/util.rs b/src/libstd/rt/util.rs
index 42546cb3c6a..b5b76f6af66 100644
--- a/src/libstd/rt/util.rs
+++ b/src/libstd/rt/util.rs
@@ -68,25 +68,11 @@ pub fn default_sched_threads() -> uint {
 }
 
 pub fn dumb_println(args: &fmt::Arguments) {
-    use io::native::stdio::stderr;
-    use io::{Writer, io_error, ResourceUnavailable};
-    use rt::task::Task;
-    use rt::local::Local;
-
-    let mut out = stderr();
-    if Local::exists(None::<Task>) {
-        let mut again = true;
-        do io_error::cond.trap(|e| {
-            again = e.kind == ResourceUnavailable;
-        }).inside {
-            while again {
-                again = false;
-                fmt::writeln(&mut out as &mut Writer, args);
-            }
-        }
-    } else {
-        fmt::writeln(&mut out as &mut Writer, args);
-    }
+    use io::native::file::FileDesc;
+    use io;
+    use libc;
+    let mut out = FileDesc::new(libc::STDERR_FILENO, false);
+    fmt::writeln(&mut out as &mut io::Writer, args);
 }
 
 pub fn abort(msg: &str) -> ! {