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:
@@ -44,7 +44,9 @@ pub mod common;
|
|||||||
pub mod errors;
|
pub mod errors;
|
||||||
|
|
||||||
#[start]
|
#[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() {
|
pub fn main() {
|
||||||
let args = os::args();
|
let args = os::args();
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ mod test {
|
|||||||
fn pool() -> SchedPool {
|
fn pool() -> SchedPool {
|
||||||
SchedPool::new(PoolConfig {
|
SchedPool::new(PoolConfig {
|
||||||
threads: 1,
|
threads: 1,
|
||||||
event_loop_factory: Some(basic::event_loop),
|
event_loop_factory: basic::event_loop,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,7 +267,7 @@ mod test {
|
|||||||
fn multi_thread() {
|
fn multi_thread() {
|
||||||
let mut pool = SchedPool::new(PoolConfig {
|
let mut pool = SchedPool::new(PoolConfig {
|
||||||
threads: 2,
|
threads: 2,
|
||||||
event_loop_factory: Some(basic::event_loop),
|
event_loop_factory: basic::event_loop,
|
||||||
});
|
});
|
||||||
|
|
||||||
for _ in range(0, 20) {
|
for _ in range(0, 20) {
|
||||||
|
|||||||
@@ -116,13 +116,34 @@
|
|||||||
//! extern crate green;
|
//! extern crate green;
|
||||||
//!
|
//!
|
||||||
//! #[start]
|
//! #[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() {
|
//! fn main() {
|
||||||
//! // this code is running in a pool of schedulers
|
//! // 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
|
//! # Using a scheduler pool
|
||||||
//!
|
//!
|
||||||
//! ```rust
|
//! ```rust
|
||||||
@@ -176,11 +197,11 @@
|
|||||||
#[allow(visible_private_types)];
|
#[allow(visible_private_types)];
|
||||||
|
|
||||||
#[cfg(test)] #[phase(syntax, link)] extern crate log;
|
#[cfg(test)] #[phase(syntax, link)] extern crate log;
|
||||||
|
#[cfg(test)] extern crate rustuv;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
|
|
||||||
use std::mem::replace;
|
use std::mem::replace;
|
||||||
use std::os;
|
use std::os;
|
||||||
use std::rt::crate_map;
|
|
||||||
use std::rt::rtio;
|
use std::rt::rtio;
|
||||||
use std::rt::thread::Thread;
|
use std::rt::thread::Thread;
|
||||||
use std::rt;
|
use std::rt;
|
||||||
@@ -207,16 +228,6 @@ pub mod sleeper_list;
|
|||||||
pub mod stack;
|
pub mod stack;
|
||||||
pub mod task;
|
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.
|
/// Set up a default runtime configuration, given compiler-supplied arguments.
|
||||||
///
|
///
|
||||||
/// This function will block until the entire pool of M:N schedulers have
|
/// 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
|
/// The return value is used as the process return code. 0 on success, 101 on
|
||||||
/// error.
|
/// 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);
|
rt::init(argc, argv);
|
||||||
let mut main = Some(main);
|
let mut main = Some(main);
|
||||||
let mut ret = None;
|
let mut ret = None;
|
||||||
simple::task().run(|| {
|
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 is ok b/c we're sure that the runtime is gone
|
||||||
unsafe { rt::cleanup() }
|
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
|
/// This function will not return until all schedulers in the associated pool
|
||||||
/// have returned.
|
/// 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
|
// Create a scheduler pool and spawn the main task into this pool. We will
|
||||||
// get notified over a channel when the main task exits.
|
// 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 (tx, rx) = channel();
|
||||||
let mut opts = TaskOpts::new();
|
let mut opts = TaskOpts::new();
|
||||||
opts.notify_chan = Some(tx);
|
opts.notify_chan = Some(tx);
|
||||||
@@ -283,7 +298,7 @@ pub struct PoolConfig {
|
|||||||
threads: uint,
|
threads: uint,
|
||||||
/// A factory function used to create new event loops. If this is not
|
/// A factory function used to create new event loops. If this is not
|
||||||
/// specified then the default event loop factory is used.
|
/// specified then the default event loop factory is used.
|
||||||
event_loop_factory: Option<fn() -> ~rtio::EventLoop>,
|
event_loop_factory: fn() -> ~rtio::EventLoop,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PoolConfig {
|
impl PoolConfig {
|
||||||
@@ -292,7 +307,7 @@ impl PoolConfig {
|
|||||||
pub fn new() -> PoolConfig {
|
pub fn new() -> PoolConfig {
|
||||||
PoolConfig {
|
PoolConfig {
|
||||||
threads: rt::default_sched_threads(),
|
threads: rt::default_sched_threads(),
|
||||||
event_loop_factory: None,
|
event_loop_factory: basic::event_loop,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -334,7 +349,6 @@ impl SchedPool {
|
|||||||
threads: nscheds,
|
threads: nscheds,
|
||||||
event_loop_factory: factory
|
event_loop_factory: factory
|
||||||
} = config;
|
} = config;
|
||||||
let factory = factory.unwrap_or(default_event_loop_factory());
|
|
||||||
assert!(nscheds > 0);
|
assert!(nscheds > 0);
|
||||||
|
|
||||||
// The pool of schedulers that will be returned from this function
|
// 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)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
use rustuv;
|
||||||
|
|
||||||
use std::comm;
|
use std::comm;
|
||||||
use std::task::TaskOpts;
|
use std::task::TaskOpts;
|
||||||
use std::rt::Runtime;
|
use std::rt::Runtime;
|
||||||
@@ -1017,7 +1019,7 @@ mod test {
|
|||||||
fn pool() -> SchedPool {
|
fn pool() -> SchedPool {
|
||||||
SchedPool::new(PoolConfig {
|
SchedPool::new(PoolConfig {
|
||||||
threads: 1,
|
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 {
|
let mut pool = SchedPool::new(PoolConfig {
|
||||||
threads: 2,
|
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
|
// This is a regression test that when there are no schedulable tasks in
|
||||||
@@ -1413,7 +1415,7 @@ mod test {
|
|||||||
fn dont_starve_1() {
|
fn dont_starve_1() {
|
||||||
let mut pool = SchedPool::new(PoolConfig {
|
let mut pool = SchedPool::new(PoolConfig {
|
||||||
threads: 2, // this must be > 1
|
threads: 2, // this must be > 1
|
||||||
event_loop_factory: Some(basic::event_loop),
|
event_loop_factory: basic::event_loop,
|
||||||
});
|
});
|
||||||
pool.spawn(TaskOpts::new(), proc() {
|
pool.spawn(TaskOpts::new(), proc() {
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
|
|||||||
@@ -494,7 +494,7 @@ mod tests {
|
|||||||
fn spawn_opts(opts: TaskOpts, f: proc()) {
|
fn spawn_opts(opts: TaskOpts, f: proc()) {
|
||||||
let mut pool = SchedPool::new(PoolConfig {
|
let mut pool = SchedPool::new(PoolConfig {
|
||||||
threads: 1,
|
threads: 1,
|
||||||
event_loop_factory: None,
|
event_loop_factory: ::rustuv::event_loop,
|
||||||
});
|
});
|
||||||
pool.spawn(opts, f);
|
pool.spawn(opts, f);
|
||||||
pool.shutdown();
|
pool.shutdown();
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ static OS_DEFAULT_STACK_ESTIMATE: uint = 1 << 20;
|
|||||||
static OS_DEFAULT_STACK_ESTIMATE: uint = 2 * (1 << 20);
|
static OS_DEFAULT_STACK_ESTIMATE: uint = 2 * (1 << 20);
|
||||||
|
|
||||||
#[lang = "start"]
|
#[lang = "start"]
|
||||||
#[cfg(not(test), not(stage0))]
|
#[cfg(not(test))]
|
||||||
pub fn lang_start(main: *u8, argc: int, argv: **u8) -> int {
|
pub fn lang_start(main: *u8, argc: int, argv: **u8) -> int {
|
||||||
use std::cast;
|
use std::cast;
|
||||||
start(argc, argv, proc() {
|
start(argc, argv, proc() {
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ mod test {
|
|||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
let mut pool = SchedPool::new(PoolConfig {
|
let mut pool = SchedPool::new(PoolConfig {
|
||||||
threads: 1,
|
threads: 1,
|
||||||
event_loop_factory: None,
|
event_loop_factory: ::event_loop,
|
||||||
});
|
});
|
||||||
|
|
||||||
pool.spawn(TaskOpts::new(), proc() {
|
pool.spawn(TaskOpts::new(), proc() {
|
||||||
@@ -188,7 +188,7 @@ mod test {
|
|||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
let mut pool = SchedPool::new(PoolConfig {
|
let mut pool = SchedPool::new(PoolConfig {
|
||||||
threads: 1,
|
threads: 1,
|
||||||
event_loop_factory: None,
|
event_loop_factory: ::event_loop,
|
||||||
});
|
});
|
||||||
|
|
||||||
pool.spawn(TaskOpts::new(), proc() {
|
pool.spawn(TaskOpts::new(), proc() {
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ use std::libc::{c_int, c_void};
|
|||||||
use std::ptr::null;
|
use std::ptr::null;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::rt::local::Local;
|
use std::rt::local::Local;
|
||||||
|
use std::rt::rtio;
|
||||||
use std::rt::task::{BlockedTask, Task};
|
use std::rt::task::{BlockedTask, Task};
|
||||||
use std::str::raw::from_c_str;
|
use std::str::raw::from_c_str;
|
||||||
use std::str;
|
use std::str;
|
||||||
@@ -76,7 +77,7 @@ pub use self::tty::TtyWatcher;
|
|||||||
// '__test' module.
|
// '__test' module.
|
||||||
#[cfg(test)] #[start]
|
#[cfg(test)] #[start]
|
||||||
fn start(argc: int, argv: **u8) -> int {
|
fn start(argc: int, argv: **u8) -> int {
|
||||||
green::start(argc, argv, __test::main)
|
green::start(argc, argv, event_loop, __test::main)
|
||||||
}
|
}
|
||||||
|
|
||||||
mod macros;
|
mod macros;
|
||||||
@@ -104,6 +105,31 @@ pub mod tty;
|
|||||||
pub mod signal;
|
pub mod signal;
|
||||||
pub mod stream;
|
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
|
/// A type that wraps a uv handle
|
||||||
pub trait UvHandle<T> {
|
pub trait UvHandle<T> {
|
||||||
fn uv_handle(&self) -> *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]
|
#[test]
|
||||||
fn test_callback_run_once() {
|
fn test_callback_run_once() {
|
||||||
use std::rt::rtio::EventLoop;
|
use std::rt::rtio::EventLoop;
|
||||||
|
|||||||
@@ -84,7 +84,7 @@
|
|||||||
// '__test' module.
|
// '__test' module.
|
||||||
#[cfg(test)] #[start]
|
#[cfg(test)] #[start]
|
||||||
fn start(argc: int, argv: **u8) -> int {
|
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;
|
pub mod macros;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ extern crate green;
|
|||||||
|
|
||||||
#[no_mangle] // this needs to get called from C
|
#[no_mangle] // this needs to get called from C
|
||||||
pub extern "C" fn foo(argc: int, argv: **u8) -> int {
|
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() {
|
spawn(proc() {
|
||||||
println!("hello");
|
println!("hello");
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ macro_rules! iotest (
|
|||||||
|
|
||||||
#[cfg(test)] #[start]
|
#[cfg(test)] #[start]
|
||||||
fn start(argc: int, argv: **u8) -> int {
|
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() {
|
iotest!(fn test_destroy_once() {
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ extern crate green;
|
|||||||
extern crate rustuv;
|
extern crate rustuv;
|
||||||
|
|
||||||
#[start]
|
#[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() {
|
fn main() {
|
||||||
native::task::spawn(proc() customtask());
|
native::task::spawn(proc() customtask());
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ static mut DROP_T: int = 0i;
|
|||||||
|
|
||||||
#[start]
|
#[start]
|
||||||
fn start(argc: int, argv: **u8) -> int {
|
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 {
|
unsafe {
|
||||||
assert_eq!(2, DROP);
|
assert_eq!(2, DROP);
|
||||||
assert_eq!(1, DROP_S);
|
assert_eq!(1, DROP_S);
|
||||||
|
|||||||
@@ -28,7 +28,9 @@ use std::io::process;
|
|||||||
use std::io::signal::{Listener, Interrupt};
|
use std::io::signal::{Listener, Interrupt};
|
||||||
|
|
||||||
#[start]
|
#[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() {
|
fn main() {
|
||||||
unsafe { libc::setsid(); }
|
unsafe { libc::setsid(); }
|
||||||
|
|||||||
Reference in New Issue
Block a user