green: Remove the dependence on the crate map
This is the final nail in the coffin for the crate map. The `start` function for libgreen now has a new added parameter which is the event loop factory instead of inferring it from the crate map. The two current valid values for this parameter are `green::basic::event_loop` and `rustuv::event_loop`.
This commit is contained in:
parent
f8f60d80bf
commit
b19261a749
|
@ -44,7 +44,9 @@ pub mod common;
|
|||
pub mod errors;
|
||||
|
||||
#[start]
|
||||
fn start(argc: int, argv: **u8) -> int { green::start(argc, argv, main) }
|
||||
fn start(argc: int, argv: **u8) -> int {
|
||||
green::start(argc, argv, rustuv::event_loop, main)
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let args = os::args();
|
||||
|
|
|
@ -237,7 +237,7 @@ mod test {
|
|||
fn pool() -> SchedPool {
|
||||
SchedPool::new(PoolConfig {
|
||||
threads: 1,
|
||||
event_loop_factory: Some(basic::event_loop),
|
||||
event_loop_factory: basic::event_loop,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -267,7 +267,7 @@ mod test {
|
|||
fn multi_thread() {
|
||||
let mut pool = SchedPool::new(PoolConfig {
|
||||
threads: 2,
|
||||
event_loop_factory: Some(basic::event_loop),
|
||||
event_loop_factory: basic::event_loop,
|
||||
});
|
||||
|
||||
for _ in range(0, 20) {
|
||||
|
|
|
@ -116,13 +116,34 @@
|
|||
//! extern crate green;
|
||||
//!
|
||||
//! #[start]
|
||||
//! fn start(argc: int, argv: **u8) -> int { green::start(argc, argv, main) }
|
||||
//! fn start(argc: int, argv: **u8) -> int {
|
||||
//! green::start(argc, argv, green::basic::event_loop, main)
|
||||
//! }
|
||||
//!
|
||||
//! fn main() {
|
||||
//! // this code is running in a pool of schedulers
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! > **Note**: This `main` funciton in this example does *not* have I/O
|
||||
//! > support. The basic event loop does not provide any support
|
||||
//!
|
||||
//! # Starting with I/O support in libgreen
|
||||
//!
|
||||
//! ```rust
|
||||
//! extern crate green;
|
||||
//! extern crate rustuv;
|
||||
//!
|
||||
//! #[start]
|
||||
//! fn start(argc: int, argv: **u8) -> int {
|
||||
//! green::start(argc, argv, rustuv::event_loop, main)
|
||||
//! }
|
||||
//!
|
||||
//! fn main() {
|
||||
//! // this code is running in a pool of schedulers all powered by libuv
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! # Using a scheduler pool
|
||||
//!
|
||||
//! ```rust
|
||||
|
@ -176,11 +197,11 @@
|
|||
#[allow(visible_private_types)];
|
||||
|
||||
#[cfg(test)] #[phase(syntax, link)] extern crate log;
|
||||
#[cfg(test)] extern crate rustuv;
|
||||
extern crate rand;
|
||||
|
||||
use std::mem::replace;
|
||||
use std::os;
|
||||
use std::rt::crate_map;
|
||||
use std::rt::rtio;
|
||||
use std::rt::thread::Thread;
|
||||
use std::rt;
|
||||
|
@ -207,16 +228,6 @@ pub mod sleeper_list;
|
|||
pub mod stack;
|
||||
pub mod task;
|
||||
|
||||
#[lang = "start"]
|
||||
#[cfg(not(test), stage0)]
|
||||
pub fn lang_start(main: *u8, argc: int, argv: **u8) -> int {
|
||||
use std::cast;
|
||||
start(argc, argv, proc() {
|
||||
let main: extern "Rust" fn() = unsafe { cast::transmute(main) };
|
||||
main();
|
||||
})
|
||||
}
|
||||
|
||||
/// Set up a default runtime configuration, given compiler-supplied arguments.
|
||||
///
|
||||
/// This function will block until the entire pool of M:N schedulers have
|
||||
|
@ -235,12 +246,14 @@ pub fn lang_start(main: *u8, argc: int, argv: **u8) -> int {
|
|||
///
|
||||
/// The return value is used as the process return code. 0 on success, 101 on
|
||||
/// error.
|
||||
pub fn start(argc: int, argv: **u8, main: proc()) -> int {
|
||||
pub fn start(argc: int, argv: **u8,
|
||||
event_loop_factory: fn() -> ~rtio::EventLoop,
|
||||
main: proc()) -> int {
|
||||
rt::init(argc, argv);
|
||||
let mut main = Some(main);
|
||||
let mut ret = None;
|
||||
simple::task().run(|| {
|
||||
ret = Some(run(main.take_unwrap()));
|
||||
ret = Some(run(event_loop_factory, main.take_unwrap()));
|
||||
});
|
||||
// unsafe is ok b/c we're sure that the runtime is gone
|
||||
unsafe { rt::cleanup() }
|
||||
|
@ -255,10 +268,12 @@ pub fn start(argc: int, argv: **u8, main: proc()) -> int {
|
|||
///
|
||||
/// This function will not return until all schedulers in the associated pool
|
||||
/// have returned.
|
||||
pub fn run(main: proc()) -> int {
|
||||
pub fn run(event_loop_factory: fn() -> ~rtio::EventLoop, main: proc()) -> int {
|
||||
// Create a scheduler pool and spawn the main task into this pool. We will
|
||||
// get notified over a channel when the main task exits.
|
||||
let mut pool = SchedPool::new(PoolConfig::new());
|
||||
let mut cfg = PoolConfig::new();
|
||||
cfg.event_loop_factory = event_loop_factory;
|
||||
let mut pool = SchedPool::new(cfg);
|
||||
let (tx, rx) = channel();
|
||||
let mut opts = TaskOpts::new();
|
||||
opts.notify_chan = Some(tx);
|
||||
|
@ -283,7 +298,7 @@ pub struct PoolConfig {
|
|||
threads: uint,
|
||||
/// A factory function used to create new event loops. If this is not
|
||||
/// specified then the default event loop factory is used.
|
||||
event_loop_factory: Option<fn() -> ~rtio::EventLoop>,
|
||||
event_loop_factory: fn() -> ~rtio::EventLoop,
|
||||
}
|
||||
|
||||
impl PoolConfig {
|
||||
|
@ -292,7 +307,7 @@ impl PoolConfig {
|
|||
pub fn new() -> PoolConfig {
|
||||
PoolConfig {
|
||||
threads: rt::default_sched_threads(),
|
||||
event_loop_factory: None,
|
||||
event_loop_factory: basic::event_loop,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -334,7 +349,6 @@ impl SchedPool {
|
|||
threads: nscheds,
|
||||
event_loop_factory: factory
|
||||
} = config;
|
||||
let factory = factory.unwrap_or(default_event_loop_factory());
|
||||
assert!(nscheds > 0);
|
||||
|
||||
// The pool of schedulers that will be returned from this function
|
||||
|
@ -503,20 +517,3 @@ impl Drop for SchedPool {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn default_event_loop_factory() -> fn() -> ~rtio::EventLoop {
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -1003,6 +1003,8 @@ fn new_sched_rng() -> XorShiftRng {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use rustuv;
|
||||
|
||||
use std::comm;
|
||||
use std::task::TaskOpts;
|
||||
use std::rt::Runtime;
|
||||
|
@ -1017,7 +1019,7 @@ mod test {
|
|||
fn pool() -> SchedPool {
|
||||
SchedPool::new(PoolConfig {
|
||||
threads: 1,
|
||||
event_loop_factory: Some(basic::event_loop),
|
||||
event_loop_factory: basic::event_loop,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1262,7 +1264,7 @@ mod test {
|
|||
|
||||
let mut pool = SchedPool::new(PoolConfig {
|
||||
threads: 2,
|
||||
event_loop_factory: None,
|
||||
event_loop_factory: rustuv::event_loop,
|
||||
});
|
||||
|
||||
// This is a regression test that when there are no schedulable tasks in
|
||||
|
@ -1413,7 +1415,7 @@ mod test {
|
|||
fn dont_starve_1() {
|
||||
let mut pool = SchedPool::new(PoolConfig {
|
||||
threads: 2, // this must be > 1
|
||||
event_loop_factory: Some(basic::event_loop),
|
||||
event_loop_factory: basic::event_loop,
|
||||
});
|
||||
pool.spawn(TaskOpts::new(), proc() {
|
||||
let (tx, rx) = channel();
|
||||
|
|
|
@ -494,7 +494,7 @@ mod tests {
|
|||
fn spawn_opts(opts: TaskOpts, f: proc()) {
|
||||
let mut pool = SchedPool::new(PoolConfig {
|
||||
threads: 1,
|
||||
event_loop_factory: None,
|
||||
event_loop_factory: ::rustuv::event_loop,
|
||||
});
|
||||
pool.spawn(opts, f);
|
||||
pool.shutdown();
|
||||
|
|
|
@ -69,7 +69,7 @@ static OS_DEFAULT_STACK_ESTIMATE: uint = 1 << 20;
|
|||
static OS_DEFAULT_STACK_ESTIMATE: uint = 2 * (1 << 20);
|
||||
|
||||
#[lang = "start"]
|
||||
#[cfg(not(test), not(stage0))]
|
||||
#[cfg(not(test))]
|
||||
pub fn lang_start(main: *u8, argc: int, argv: **u8) -> int {
|
||||
use std::cast;
|
||||
start(argc, argv, proc() {
|
||||
|
|
|
@ -167,7 +167,7 @@ mod test {
|
|||
let (tx, rx) = channel();
|
||||
let mut pool = SchedPool::new(PoolConfig {
|
||||
threads: 1,
|
||||
event_loop_factory: None,
|
||||
event_loop_factory: ::event_loop,
|
||||
});
|
||||
|
||||
pool.spawn(TaskOpts::new(), proc() {
|
||||
|
@ -188,7 +188,7 @@ mod test {
|
|||
let (tx, rx) = channel();
|
||||
let mut pool = SchedPool::new(PoolConfig {
|
||||
threads: 1,
|
||||
event_loop_factory: None,
|
||||
event_loop_factory: ::event_loop,
|
||||
});
|
||||
|
||||
pool.spawn(TaskOpts::new(), proc() {
|
||||
|
|
|
@ -54,6 +54,7 @@ use std::libc::{c_int, c_void};
|
|||
use std::ptr::null;
|
||||
use std::ptr;
|
||||
use std::rt::local::Local;
|
||||
use std::rt::rtio;
|
||||
use std::rt::task::{BlockedTask, Task};
|
||||
use std::str::raw::from_c_str;
|
||||
use std::str;
|
||||
|
@ -76,7 +77,7 @@ pub use self::tty::TtyWatcher;
|
|||
// '__test' module.
|
||||
#[cfg(test)] #[start]
|
||||
fn start(argc: int, argv: **u8) -> int {
|
||||
green::start(argc, argv, __test::main)
|
||||
green::start(argc, argv, event_loop, __test::main)
|
||||
}
|
||||
|
||||
mod macros;
|
||||
|
@ -104,6 +105,31 @@ pub mod tty;
|
|||
pub mod signal;
|
||||
pub mod stream;
|
||||
|
||||
/// Creates a new event loop which is powered by libuv
|
||||
///
|
||||
/// This function is used in tandem with libgreen's `PoolConfig` type as a value
|
||||
/// for the `event_loop_factory` field. Using this function as the event loop
|
||||
/// factory will power programs with libuv and enable green threading.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// extern crate rustuv;
|
||||
/// extern crate green;
|
||||
///
|
||||
/// #[start]
|
||||
/// fn start(argc: int, argv: **u8) -> int {
|
||||
/// green::start(argc, argv, rustuv::event_loop, main)
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// // this code is running inside of a green task powered by libuv
|
||||
/// }
|
||||
/// ```
|
||||
pub fn event_loop() -> ~rtio::EventLoop {
|
||||
~uvio::UvEventLoop::new() as ~rtio::EventLoop
|
||||
}
|
||||
|
||||
/// A type that wraps a uv handle
|
||||
pub trait UvHandle<T> {
|
||||
fn uv_handle(&self) -> *T;
|
||||
|
|
|
@ -105,12 +105,6 @@ impl rtio::EventLoop for UvEventLoop {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[lang = "event_loop_factory"]
|
||||
pub fn new_loop() -> ~rtio::EventLoop {
|
||||
~UvEventLoop::new() as ~rtio::EventLoop
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_callback_run_once() {
|
||||
use std::rt::rtio::EventLoop;
|
||||
|
|
|
@ -84,7 +84,7 @@
|
|||
// '__test' module.
|
||||
#[cfg(test)] #[start]
|
||||
fn start(argc: int, argv: **u8) -> int {
|
||||
green::start(argc, argv, __test::main)
|
||||
green::start(argc, argv, rustuv::event_loop, __test::main)
|
||||
}
|
||||
|
||||
pub mod macros;
|
||||
|
|
|
@ -16,7 +16,7 @@ extern crate green;
|
|||
|
||||
#[no_mangle] // this needs to get called from C
|
||||
pub extern "C" fn foo(argc: int, argv: **u8) -> int {
|
||||
green::start(argc, argv, proc() {
|
||||
green::start(argc, argv, rustuv::event_loop, proc() {
|
||||
spawn(proc() {
|
||||
println!("hello");
|
||||
});
|
||||
|
|
|
@ -49,7 +49,7 @@ macro_rules! iotest (
|
|||
|
||||
#[cfg(test)] #[start]
|
||||
fn start(argc: int, argv: **u8) -> int {
|
||||
green::start(argc, argv, __test::main)
|
||||
green::start(argc, argv, rustuv::event_loop, __test::main)
|
||||
}
|
||||
|
||||
iotest!(fn test_destroy_once() {
|
||||
|
|
|
@ -15,7 +15,9 @@ extern crate green;
|
|||
extern crate rustuv;
|
||||
|
||||
#[start]
|
||||
fn start(argc: int, argv: **u8) -> int { green::start(argc, argv, main) }
|
||||
fn start(argc: int, argv: **u8) -> int {
|
||||
green::start(argc, argv, rustuv::event_loop, main)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
native::task::spawn(proc() customtask());
|
||||
|
|
|
@ -18,7 +18,7 @@ static mut DROP_T: int = 0i;
|
|||
|
||||
#[start]
|
||||
fn start(argc: int, argv: **u8) -> int {
|
||||
let ret = green::start(argc, argv, main);
|
||||
let ret = green::start(argc, argv, green::basic::event_loop, main);
|
||||
unsafe {
|
||||
assert_eq!(2, DROP);
|
||||
assert_eq!(1, DROP_S);
|
||||
|
|
|
@ -28,7 +28,9 @@ use std::io::process;
|
|||
use std::io::signal::{Listener, Interrupt};
|
||||
|
||||
#[start]
|
||||
fn start(argc: int, argv: **u8) -> int { green::start(argc, argv, main) }
|
||||
fn start(argc: int, argv: **u8) -> int {
|
||||
green::start(argc, argv, rustuv::event_loop, main)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe { libc::setsid(); }
|
||||
|
|
Loading…
Reference in New Issue