]> git.lizzy.rs Git - rust.git/commitdiff
green: Allow specifying an IoFactory for pools
authorAlex Crichton <alex@alexcrichton.com>
Sat, 14 Dec 2013 02:28:18 +0000 (18:28 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Wed, 25 Dec 2013 03:59:53 +0000 (19:59 -0800)
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.

src/libgreen/lib.rs
src/librustuv/homing.rs
src/librustuv/uvio.rs
src/libstd/rt/crate_map.rs

index 9a3f27f7dbc4c2ab0af6d169ed87fd40a7a245a3..82d5bc83e2efd0e05f64f10856b5baaa9d3d3764 100644 (file)
@@ -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;
 }
index 1f9e3831e205711b5c4639af5fe28ca0e7578541..1ee64398ca382908f48132d5ed7311d0e52bc3a4 100644 (file)
@@ -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();
index 57bb0cfdc7af8f109cc076fe5b4ec91ba10b6d24..210ee2fc4511a126e845d87827967a741709e309 100644 (file)
@@ -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
 }
 
index 22fc3f0ab56c0a082da889eb4a1b7089d5f8401b..d9b40cfbb6e8ce329b27bb4026189e8978fc91c0 100644 (file)
@@ -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))]