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.rs54
-rw-r--r--src/libstd/rt/sched.rs17
-rw-r--r--src/libstd/rt/test.rs7
-rw-r--r--src/libstd/rt/uv/uvio.rs6
6 files changed, 87 insertions, 41 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 eaaf8c43281..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};
@@ -87,15 +86,13 @@ pub use self::util::set_exit_status;
 // method...
 pub use self::util::default_sched_threads;
 
+// Re-export of the functionality in the kill module
+pub use self::kill::{KillHandle, BlockedTask};
+
 // XXX: these probably shouldn't be public...
 #[doc(hidden)]
 pub mod shouldnt_be_public {
-    pub use super::sched::Scheduler;
-    pub use super::kill::KillHandle;
-    pub use super::thread::Thread;
-    pub use super::work_queue::WorkQueue;
     pub use super::select::SelectInner;
-    pub use super::rtio::EventLoop;
     pub use super::select::{SelectInner, SelectPortInner};
     pub use super::local_ptr::maybe_tls_key;
 }
@@ -116,15 +113,16 @@ pub mod task;
 mod kill;
 
 /// The coroutine task scheduler, built on the `io` event loop.
-mod sched;
+pub mod sched;
 
 /// Synchronous I/O.
 pub mod io;
 
 /// The EventLoop and internal synchronous I/O interface.
-mod rtio;
+pub mod rtio;
 
 /// libuv and default rtio implementation.
+#[cfg(stage0)]
 pub mod uv;
 
 /// The Local trait for types that are accessible via thread-local
@@ -132,10 +130,10 @@ pub mod uv;
 pub mod local;
 
 /// A parallel work-stealing deque.
-mod work_queue;
+pub mod work_queue;
 
 /// A parallel queue.
-mod message_queue;
+pub mod message_queue;
 
 /// A mostly lock-free multi-producer, single consumer queue.
 mod mpsc_queue;
@@ -144,7 +142,7 @@ mod mpsc_queue;
 mod mpmc_bounded_queue;
 
 /// A parallel data structure for tracking sleeping schedulers.
-mod sleeper_list;
+pub mod sleeper_list;
 
 /// Stack segments and caching.
 pub mod stack;
@@ -153,7 +151,7 @@ pub mod stack;
 mod context;
 
 /// Bindings to system threading libraries.
-mod thread;
+pub mod thread;
 
 /// The runtime configuration, read from environment variables.
 pub mod env;
@@ -289,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(),
@@ -313,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(),
@@ -327,7 +325,7 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
         // waking up schedulers for work stealing; since this is a
         // non-work-stealing scheduler it should not be adding itself
         // to the list.
-        main_handle.send_shutdown();
+        main_handle.send(Shutdown);
         Some(main_sched)
     } else {
         None
@@ -464,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 93056314b14..fd4dab60ff3 100644
--- a/src/libstd/rt/sched.rs
+++ b/src/libstd/rt/sched.rs
@@ -529,7 +529,7 @@ impl Scheduler {
 
         match self.sleeper_list.casual_pop() {
             Some(handle) => {
-                        let mut handle = handle;
+                let mut handle = handle;
                 handle.send(Wake)
             }
             None => { (/* pass */) }
@@ -800,12 +800,6 @@ impl SchedHandle {
         self.queue.push(msg);
         self.remote.fire();
     }
-    pub fn send_task_from_friend(&mut self, friend: ~Task) {
-        self.send(TaskFromFriend(friend));
-    }
-    pub fn send_shutdown(&mut self) {
-        self.send(Shutdown);
-    }
 }
 
 struct CleanupJob {
@@ -1001,7 +995,6 @@ mod test {
 
     #[test]
     fn test_schedule_home_states() {
-
         use rt::sleeper_list::SleeperList;
         use rt::work_queue::WorkQueue;
         use rt::sched::Shutdown;
@@ -1248,15 +1241,15 @@ mod test {
         use comm::{GenericPort, GenericChan};
 
         do run_in_mt_newsched_task {
-                let (end_port, end_chan) = oneshot();
+            let (end_port, end_chan) = oneshot();
 
             let n_tasks = 10;
             let token = 2000;
 
-                let (p, ch1) = stream();
+            let (p, ch1) = stream();
             let mut p = p;
-                ch1.send((token, end_chan));
-                let mut i = 2;
+            ch1.send((token, end_chan));
+            let mut i = 2;
             while i <= n_tasks {
                 let (next_p, ch) = stream();
                 let imm_i = i;
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 bd8466a7925..2d3ecbbd689 100644
--- a/src/libstd/rt/uv/uvio.rs
+++ b/src/libstd/rt/uv/uvio.rs
@@ -236,6 +236,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,