green: Allow specifying an IoFactory for pools
This allows creation of different sched pools with different io factories. Namely, this will be used to test the basic I/O loop in the green crate. This can also be used to override the global default.
This commit is contained in:
parent
8be66e212b
commit
1a6d920e3d
@ -115,6 +115,9 @@ pub fn run(main: proc()) -> int {
|
||||
pub struct PoolConfig {
|
||||
/// The number of schedulers (OS threads) to spawn into this M:N pool.
|
||||
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>,
|
||||
}
|
||||
|
||||
impl PoolConfig {
|
||||
@ -123,6 +126,7 @@ impl PoolConfig {
|
||||
pub fn new() -> PoolConfig {
|
||||
PoolConfig {
|
||||
threads: rt::default_sched_threads(),
|
||||
event_loop_factory: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -138,6 +142,7 @@ pub struct SchedPool {
|
||||
priv stack_pool: StackPool,
|
||||
priv deque_pool: deque::BufferPool<~task::GreenTask>,
|
||||
priv sleepers: SleeperList,
|
||||
priv factory: fn() -> ~rtio::EventLoop,
|
||||
}
|
||||
|
||||
impl SchedPool {
|
||||
@ -148,7 +153,11 @@ impl SchedPool {
|
||||
pub fn new(config: PoolConfig) -> SchedPool {
|
||||
static mut POOL_ID: AtomicUint = INIT_ATOMIC_UINT;
|
||||
|
||||
let PoolConfig { threads: nscheds } = config;
|
||||
let PoolConfig {
|
||||
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
|
||||
@ -161,6 +170,7 @@ pub fn new(config: PoolConfig) -> SchedPool {
|
||||
stack_pool: StackPool::new(),
|
||||
deque_pool: deque::BufferPool::new(),
|
||||
next_friend: 0,
|
||||
factory: factory,
|
||||
};
|
||||
|
||||
// Create a work queue for each scheduler, ntimes. Create an extra
|
||||
@ -176,7 +186,7 @@ pub fn new(config: PoolConfig) -> SchedPool {
|
||||
rtdebug!("inserting a regular scheduler");
|
||||
|
||||
let mut sched = ~Scheduler::new(pool.id,
|
||||
new_event_loop(),
|
||||
(pool.factory)(),
|
||||
worker,
|
||||
pool.stealers.clone(),
|
||||
pool.sleepers.clone());
|
||||
@ -232,7 +242,7 @@ pub fn spawn_sched(&mut self) -> SchedHandle {
|
||||
// other schedulers as well as having a stealer handle to all other
|
||||
// schedulers.
|
||||
let mut sched = ~Scheduler::new(self.id,
|
||||
new_event_loop(),
|
||||
(self.factory)(),
|
||||
worker,
|
||||
self.stealers.clone(),
|
||||
self.sleepers.clone());
|
||||
@ -270,13 +280,13 @@ fn drop(&mut self) {
|
||||
}
|
||||
}
|
||||
|
||||
fn new_event_loop() -> ~rtio::EventLoop {
|
||||
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()
|
||||
Some(factory) => return factory
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -284,5 +294,5 @@ fn new_event_loop() -> ~rtio::EventLoop {
|
||||
// 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();
|
||||
return basic::event_loop;
|
||||
}
|
||||
|
@ -161,7 +161,10 @@ mod test {
|
||||
#[test]
|
||||
fn test_homing_closes_correctly() {
|
||||
let (port, chan) = Chan::new();
|
||||
let mut pool = SchedPool::new(PoolConfig { threads: 1 });
|
||||
let mut pool = SchedPool::new(PoolConfig {
|
||||
threads: 1,
|
||||
event_loop_factory: None,
|
||||
});
|
||||
|
||||
do pool.spawn(TaskOpts::new()) {
|
||||
let listener = UdpWatcher::bind(local_loop(), next_test_ip4());
|
||||
@ -179,7 +182,10 @@ fn test_homing_closes_correctly() {
|
||||
#[test]
|
||||
fn test_homing_read() {
|
||||
let (port, chan) = Chan::new();
|
||||
let mut pool = SchedPool::new(PoolConfig { threads: 1 });
|
||||
let mut pool = SchedPool::new(PoolConfig {
|
||||
threads: 1,
|
||||
event_loop_factory: None,
|
||||
});
|
||||
|
||||
do pool.spawn(TaskOpts::new()) {
|
||||
let addr1 = next_test_ip4();
|
||||
|
@ -96,7 +96,7 @@ fn io<'a>(&'a mut self) -> Option<&'a mut rtio::IoFactory> {
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[lang = "event_loop_factory"]
|
||||
pub extern "C" fn new_loop() -> ~rtio::EventLoop {
|
||||
pub fn new_loop() -> ~rtio::EventLoop {
|
||||
~UvEventLoop::new() as ~rtio::EventLoop
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ pub struct CrateMap<'a> {
|
||||
version: i32,
|
||||
entries: &'a [ModEntry<'a>],
|
||||
children: &'a [&'a CrateMap<'a>],
|
||||
event_loop_factory: Option<extern "C" fn() -> ~EventLoop>,
|
||||
event_loop_factory: Option<fn() -> ~EventLoop>,
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
|
Loading…
Reference in New Issue
Block a user