diff options
Diffstat (limited to 'src/libstd/rt')
| -rw-r--r-- | src/libstd/rt/crate_map.rs | 38 | ||||
| -rw-r--r-- | src/libstd/rt/io/net/tcp.rs | 6 | ||||
| -rw-r--r-- | src/libstd/rt/mod.rs | 54 | ||||
| -rw-r--r-- | src/libstd/rt/sched.rs | 17 | ||||
| -rw-r--r-- | src/libstd/rt/test.rs | 7 | ||||
| -rw-r--r-- | src/libstd/rt/uv/uvio.rs | 6 |
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, |
