about summary refs log tree commit diff
path: root/src/libstd/rt
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstd/rt')
-rw-r--r--src/libstd/rt/crate_map.rs38
-rw-r--r--src/libstd/rt/io/net/tcp.rs6
-rw-r--r--src/libstd/rt/mod.rs32
-rw-r--r--src/libstd/rt/sched.rs1
-rw-r--r--src/libstd/rt/test.rs7
-rw-r--r--src/libstd/rt/uv/uvio.rs6
6 files changed, 72 insertions, 18 deletions
diff --git a/src/libstd/rt/crate_map.rs b/src/libstd/rt/crate_map.rs
index dd71426938d..16b41276788 100644
--- a/src/libstd/rt/crate_map.rs
+++ b/src/libstd/rt/crate_map.rs
@@ -12,6 +12,8 @@ use container::MutableSet;
 use hashmap::HashSet;
 use option::{Some, None, Option};
 use vec::ImmutableVector;
+#[cfg(not(stage0))]
+use rt::rtio::EventLoop;
 
 // Need to tell the linker on OS X to not barf on undefined symbols
 // and instead look them up at runtime, which we need to resolve
@@ -25,18 +27,32 @@ pub struct ModEntry<'self> {
     log_level: *mut u32
 }
 
+#[cfg(stage0)]
 pub struct CrateMap<'self> {
-     priv version: i32,
-     priv entries: &'self [ModEntry<'self>],
-     priv children: &'self [&'self CrateMap<'self>]
+    version: i32,
+    entries: &'self [ModEntry<'self>],
+    children: &'self [&'self CrateMap<'self>]
+}
+
+#[cfg(not(stage0))]
+pub struct CrateMap<'self> {
+    version: i32,
+    entries: &'self [ModEntry<'self>],
+    children: &'self [&'self CrateMap<'self>],
+    event_loop_factory: Option<extern "C" fn() -> ~EventLoop>,
 }
 
 #[cfg(not(windows))]
 pub fn get_crate_map() -> Option<&'static CrateMap<'static>> {
     extern {
+        #[cfg(stage0)]
         #[weak_linkage]
         #[link_name = "_rust_crate_map_toplevel"]
         static CRATE_MAP: CrateMap<'static>;
+
+        #[cfg(not(stage0))]
+        #[crate_map]
+        static CRATE_MAP: CrateMap<'static>;
     }
 
     let ptr: (*CrateMap) = &'static CRATE_MAP;
@@ -108,6 +124,7 @@ pub fn iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: &fn(&ModEntry)) {
 
 #[cfg(test)]
 mod tests {
+    use option::None;
     use rt::crate_map::{CrateMap, ModEntry, iter_crate_map};
 
     #[test]
@@ -121,13 +138,15 @@ mod tests {
         let child_crate = CrateMap {
             version: 2,
             entries: entries,
-            children: []
+            children: [],
+            event_loop_factory: None,
         };
 
         let root_crate = CrateMap {
             version: 2,
             entries: [],
-            children: [&child_crate, &child_crate]
+            children: [&child_crate, &child_crate],
+            event_loop_factory: None,
         };
 
         let mut cnt = 0;
@@ -150,7 +169,8 @@ mod tests {
                 ModEntry { name: "c::m1", log_level: &mut level2},
                 ModEntry { name: "c::m2", log_level: &mut level3},
             ],
-            children: []
+            children: [],
+            event_loop_factory: None,
         };
 
         let child_crate1 = CrateMap {
@@ -158,7 +178,8 @@ mod tests {
             entries: [
                 ModEntry { name: "t::f1", log_level: &mut 1},
             ],
-            children: [&child_crate2]
+            children: [&child_crate2],
+            event_loop_factory: None,
         };
 
         let root_crate = CrateMap {
@@ -166,7 +187,8 @@ mod tests {
             entries: [
                 ModEntry { name: "t::f2", log_level: &mut 0},
             ],
-            children: [&child_crate1]
+            children: [&child_crate1],
+            event_loop_factory: None,
         };
 
         let mut cnt = 0;
diff --git a/src/libstd/rt/io/net/tcp.rs b/src/libstd/rt/io/net/tcp.rs
index 6314c0755a0..fb7c6766fd8 100644
--- a/src/libstd/rt/io/net/tcp.rs
+++ b/src/libstd/rt/io/net/tcp.rs
@@ -383,7 +383,8 @@ mod test {
                         //     on windows
                         assert!(e.kind == ConnectionReset ||
                                 e.kind == BrokenPipe ||
-                                e.kind == ConnectionAborted);
+                                e.kind == ConnectionAborted,
+                                "unknown error: {:?}", e);
                         stop = true;
                     }).inside {
                         stream.write(buf);
@@ -420,7 +421,8 @@ mod test {
                         //     on windows
                         assert!(e.kind == ConnectionReset ||
                                 e.kind == BrokenPipe ||
-                                e.kind == ConnectionAborted);
+                                e.kind == ConnectionAborted,
+                                "unknown error: {:?}", e);
                         stop = true;
                     }).inside {
                         stream.write(buf);
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index 21fdf0e50a1..d8d07f14021 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -68,7 +68,6 @@ use rt::sched::{Scheduler, Shutdown};
 use rt::sleeper_list::SleeperList;
 use rt::task::UnwindResult;
 use rt::task::{Task, SchedTask, GreenTask, Sched};
-use rt::uv::uvio::UvEventLoop;
 use unstable::atomics::{AtomicInt, AtomicBool, SeqCst};
 use unstable::sync::UnsafeArc;
 use vec::{OwnedVector, MutableVector, ImmutableVector};
@@ -123,6 +122,7 @@ pub mod io;
 pub mod rtio;
 
 /// libuv and default rtio implementation.
+#[cfg(stage0)]
 pub mod uv;
 
 /// The Local trait for types that are accessible via thread-local
@@ -287,7 +287,7 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
         rtdebug!("inserting a regular scheduler");
 
         // Every scheduler is driven by an I/O event loop.
-        let loop_ = ~UvEventLoop::new() as ~rtio::EventLoop;
+        let loop_ = new_event_loop();
         let mut sched = ~Scheduler::new(loop_,
                                         work_queue.clone(),
                                         work_queues.clone(),
@@ -311,7 +311,7 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
         // set.
         let work_queue = WorkQueue::new();
 
-        let main_loop = ~UvEventLoop::new() as ~rtio::EventLoop;
+        let main_loop = new_event_loop();
         let mut main_sched = ~Scheduler::new_special(main_loop,
                                                      work_queue,
                                                      work_queues.clone(),
@@ -462,3 +462,29 @@ pub fn in_green_task_context() -> bool {
         }
     }
 }
+
+#[cfg(stage0)]
+pub fn new_event_loop() -> ~rtio::EventLoop {
+    use rt::uv::uvio::UvEventLoop;
+    ~UvEventLoop::new() as ~rtio::EventLoop
+}
+
+#[cfg(not(stage0))]
+pub fn new_event_loop() -> ~rtio::EventLoop {
+    #[fixed_stack_segment]; #[allow(cstack)];
+
+    match crate_map::get_crate_map() {
+        None => {}
+        Some(map) => {
+            match map.event_loop_factory {
+                None => {}
+                Some(factory) => return factory()
+            }
+        }
+    }
+
+    // If the crate map didn't specify a factory to create an event loop, then
+    // instead just use a basic event loop missing all I/O services to at least
+    // get the scheduler running.
+    return basic::event_loop();
+}
diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs
index 3ee822ced2d..4b033363402 100644
--- a/src/libstd/rt/sched.rs
+++ b/src/libstd/rt/sched.rs
@@ -1013,7 +1013,6 @@ mod test {
 
     #[test]
     fn test_schedule_home_states() {
-
         use rt::sleeper_list::SleeperList;
         use rt::work_queue::WorkQueue;
         use rt::sched::Shutdown;
diff --git a/src/libstd/rt/test.rs b/src/libstd/rt/test.rs
index 5f78b9fc959..55a8db89d3c 100644
--- a/src/libstd/rt/test.rs
+++ b/src/libstd/rt/test.rs
@@ -24,13 +24,12 @@ use rand;
 use result::{Result, Ok, Err};
 use rt::basic;
 use rt::comm::oneshot;
-use rt::rtio::EventLoop;
+use rt::new_event_loop;
 use rt::sched::Scheduler;
 use rt::sleeper_list::SleeperList;
 use rt::task::Task;
 use rt::task::UnwindResult;
 use rt::thread::Thread;
-use rt::uv::uvio::UvEventLoop;
 use rt::work_queue::WorkQueue;
 use unstable::{run_in_bare_thread};
 use vec::{OwnedVector, MutableVector, ImmutableVector};
@@ -40,7 +39,7 @@ pub fn new_test_uv_sched() -> Scheduler {
     let queue = WorkQueue::new();
     let queues = ~[queue.clone()];
 
-    let mut sched = Scheduler::new(~UvEventLoop::new() as ~EventLoop,
+    let mut sched = Scheduler::new(new_event_loop(),
                                    queue,
                                    queues,
                                    SleeperList::new());
@@ -237,7 +236,7 @@ pub fn run_in_mt_newsched_task(f: ~fn()) {
         }
 
         for i in range(0u, nthreads) {
-            let loop_ = ~UvEventLoop::new() as ~EventLoop;
+            let loop_ = new_event_loop();
             let mut sched = ~Scheduler::new(loop_,
                                             work_queues[i].clone(),
                                             work_queues.clone(),
diff --git a/src/libstd/rt/uv/uvio.rs b/src/libstd/rt/uv/uvio.rs
index a8cde826125..497d790b4a9 100644
--- a/src/libstd/rt/uv/uvio.rs
+++ b/src/libstd/rt/uv/uvio.rs
@@ -237,6 +237,12 @@ impl EventLoop for UvEventLoop {
     }
 }
 
+#[cfg(not(stage0))]
+#[lang = "event_loop_factory"]
+pub extern "C" fn new_loop() -> ~EventLoop {
+    ~UvEventLoop::new() as ~EventLoop
+}
+
 pub struct UvPausibleIdleCallback {
     priv watcher: IdleWatcher,
     priv idle_flag: bool,