159
159
//!
160
160
//! # Using a scheduler pool
161
161
//!
162
+ //! This library adds a `GreenTaskBuilder` trait that extends the methods
163
+ //! available on `std::task::TaskBuilder` to allow spawning a green task,
164
+ //! possibly pinned to a particular scheduler thread:
165
+ //!
162
166
//! ```rust
163
- //! use std::rt::task::TaskOpts;
164
- //! use green::{SchedPool, PoolConfig};
165
- //! use green::sched::{PinnedTask, TaskFromFriend};
167
+ //! use std::task::TaskBuilder;
168
+ //! use green::{SchedPool, PoolConfig, GreenTaskBuilder};
166
169
//!
167
170
//! let config = PoolConfig::new();
168
171
//! let mut pool = SchedPool::new(config);
169
172
//!
170
173
//! // Spawn tasks into the pool of schedulers
171
- //! pool.spawn(TaskOpts ::new(), proc() {
174
+ //! TaskBuilder ::new().green(&mut pool).spawn( proc() {
172
175
//! // this code is running inside the pool of schedulers
173
176
//!
174
177
//! spawn(proc() {
181
184
//! let mut handle = pool.spawn_sched();
182
185
//!
183
186
//! // Pin a task to the spawned scheduler
184
- //! let task = pool.task(TaskOpts::new(), proc() { /* ... */ });
185
- //! handle.send(PinnedTask(task));
186
- //!
187
- //! // Schedule a task on this new scheduler
188
- //! let task = pool.task(TaskOpts::new(), proc() { /* ... */ });
189
- //! handle.send(TaskFromFriend(task));
187
+ //! TaskBuilder::new().green_pinned(&mut pool, &mut handle).spawn(proc() {
188
+ //! /* ... */
189
+ //! });
190
190
//!
191
191
//! // Handles keep schedulers alive, so be sure to drop all handles before
192
192
//! // destroying the sched pool
209
209
// NB this does *not* include globs, please keep it that way.
210
210
#![ feature( macro_rules, phase) ]
211
211
#![ allow( visible_private_types) ]
212
+ #![ allow( deprecated) ]
213
+ #![ feature( default_type_params) ]
212
214
213
215
#[ cfg( test) ] #[ phase( plugin, link) ] extern crate log;
214
216
#[ cfg( test) ] extern crate rustuv;
@@ -224,8 +226,9 @@ use std::rt::task::TaskOpts;
224
226
use std:: rt;
225
227
use std:: sync:: atomics:: { SeqCst , AtomicUint , INIT_ATOMIC_UINT } ;
226
228
use std:: sync:: deque;
229
+ use std:: task:: { TaskBuilder , Spawner } ;
227
230
228
- use sched:: { Shutdown , Scheduler , SchedHandle , TaskFromFriend , NewNeighbor } ;
231
+ use sched:: { Shutdown , Scheduler , SchedHandle , TaskFromFriend , PinnedTask , NewNeighbor } ;
229
232
use sleeper_list:: SleeperList ;
230
233
use stack:: StackPool ;
231
234
use task:: GreenTask ;
@@ -444,6 +447,7 @@ impl SchedPool {
444
447
/// This is useful to create a task which can then be sent to a specific
445
448
/// scheduler created by `spawn_sched` (and possibly pin it to that
446
449
/// scheduler).
450
+ #[ deprecated = "use the green and green_pinned methods of GreenTaskBuilder instead" ]
447
451
pub fn task ( & mut self , opts : TaskOpts , f : proc ( ) : Send ) -> Box < GreenTask > {
448
452
GreenTask :: configure ( & mut self . stack_pool , opts, f)
449
453
}
@@ -454,6 +458,7 @@ impl SchedPool {
454
458
/// New tasks are spawned in a round-robin fashion to the schedulers in this
455
459
/// pool, but tasks can certainly migrate among schedulers once they're in
456
460
/// the pool.
461
+ #[ deprecated = "use the green and green_pinned methods of GreenTaskBuilder instead" ]
457
462
pub fn spawn ( & mut self , opts : TaskOpts , f : proc ( ) : Send ) {
458
463
let task = self . task ( opts, f) ;
459
464
@@ -563,3 +568,54 @@ impl Drop for SchedPool {
563
568
}
564
569
}
565
570
}
571
+
572
+ /// A spawner for green tasks
573
+ pub struct GreenSpawner < ' a > {
574
+ pool : & ' a mut SchedPool ,
575
+ handle : Option < & ' a mut SchedHandle >
576
+ }
577
+
578
+ impl < ' a > Spawner for GreenSpawner < ' a > {
579
+ #[ inline]
580
+ fn spawn ( self , opts : TaskOpts , f : proc ( ) : Send ) {
581
+ let GreenSpawner { pool, handle } = self ;
582
+ match handle {
583
+ None => pool. spawn ( opts, f) ,
584
+ Some ( h) => h. send ( PinnedTask ( pool. task ( opts, f) ) )
585
+ }
586
+ }
587
+ }
588
+
589
+ /// An extension trait adding `green` configuration methods to `TaskBuilder`.
590
+ pub trait GreenTaskBuilder {
591
+ fn green < ' a > ( self , & ' a mut SchedPool ) -> TaskBuilder < GreenSpawner < ' a > > ;
592
+ fn green_pinned < ' a > ( self , & ' a mut SchedPool , & ' a mut SchedHandle )
593
+ -> TaskBuilder < GreenSpawner < ' a > > ;
594
+ }
595
+
596
+ impl < S : Spawner > GreenTaskBuilder for TaskBuilder < S > {
597
+ fn green < ' a > ( self , pool : & ' a mut SchedPool ) -> TaskBuilder < GreenSpawner < ' a > > {
598
+ self . spawner ( GreenSpawner { pool : pool, handle : None } )
599
+ }
600
+
601
+ fn green_pinned < ' a > ( self , pool : & ' a mut SchedPool , handle : & ' a mut SchedHandle )
602
+ -> TaskBuilder < GreenSpawner < ' a > > {
603
+ self . spawner ( GreenSpawner { pool : pool, handle : Some ( handle) } )
604
+ }
605
+ }
606
+
607
+ #[ cfg( test) ]
608
+ mod test {
609
+ use std:: task:: TaskBuilder ;
610
+ use super :: { SchedPool , PoolConfig , GreenTaskBuilder } ;
611
+
612
+ #[ test]
613
+ fn test_green_builder ( ) {
614
+ let mut pool = SchedPool :: new ( PoolConfig :: new ( ) ) ;
615
+ let res = TaskBuilder :: new ( ) . green ( & mut pool) . try ( proc ( ) {
616
+ "Success!" . to_string ( )
617
+ } ) ;
618
+ assert_eq ! ( res. ok( ) . unwrap( ) , "Success!" . to_string( ) ) ;
619
+ pool. shutdown ( ) ;
620
+ }
621
+ }
0 commit comments