|
9 | 9 | // except according to those terms.
|
10 | 10 |
|
11 | 11 | use uint;
|
12 |
| -use option::*; |
| 12 | +use option::{Option, Some, None}; |
13 | 13 | use cell::Cell;
|
| 14 | +use clone::Clone; |
| 15 | +use container::Container; |
| 16 | +use vec::OwnedVector; |
14 | 17 | use result::{Result, Ok, Err};
|
| 18 | +use unstable::run_in_bare_thread; |
15 | 19 | use super::io::net::ip::{IpAddr, Ipv4};
|
16 | 20 | use rt::task::Task;
|
17 | 21 | use rt::thread::Thread;
|
18 | 22 | use rt::local::Local;
|
19 |
| -use rt::sched::Scheduler; |
| 23 | +use rt::sched::{Scheduler, Coroutine}; |
| 24 | +use rt::sleeper_list::SleeperList; |
| 25 | +use rt::work_queue::WorkQueue; |
20 | 26 |
|
21 | 27 | pub fn new_test_uv_sched() -> Scheduler {
|
22 | 28 | use rt::uv::uvio::UvEventLoop;
|
@@ -46,6 +52,59 @@ pub fn run_in_newsched_task(f: ~fn()) {
|
46 | 52 | }
|
47 | 53 | }
|
48 | 54 |
|
| 55 | +/// Create more than one scheduler and run a function in a task |
| 56 | +/// in one of the schedulers. The schedulers will stay alive |
| 57 | +/// until the function `f` returns. |
| 58 | +pub fn run_in_mt_newsched_task(f: ~fn()) { |
| 59 | + use rt::uv::uvio::UvEventLoop; |
| 60 | + |
| 61 | + let f_cell = Cell(f); |
| 62 | + |
| 63 | + do run_in_bare_thread { |
| 64 | + static N: uint = 2; |
| 65 | + |
| 66 | + let sleepers = SleeperList::new(); |
| 67 | + let work_queue = WorkQueue::new(); |
| 68 | + |
| 69 | + let mut handles = ~[]; |
| 70 | + let mut scheds = ~[]; |
| 71 | + |
| 72 | + for uint::range(0, N) |i| { |
| 73 | + let loop_ = ~UvEventLoop::new(); |
| 74 | + let mut sched = ~Scheduler::new(loop_, work_queue.clone(), sleepers.clone()); |
| 75 | + let handle = sched.make_handle(); |
| 76 | + handles.push(handle); |
| 77 | + scheds.push(sched); |
| 78 | + } |
| 79 | + |
| 80 | + let f_cell = Cell(f_cell.take()); |
| 81 | + let handles = handles; // Freeze |
| 82 | + let main_task = ~do Coroutine::new(&mut scheds[0].stack_pool) { |
| 83 | + f_cell.take()(); |
| 84 | + // Hold on to handles until the function exits. This keeps the schedulers alive. |
| 85 | + let _captured_handles = &handles; |
| 86 | + }; |
| 87 | + |
| 88 | + scheds[0].enqueue_task(main_task); |
| 89 | + |
| 90 | + let mut threads = ~[]; |
| 91 | + |
| 92 | + while !scheds.is_empty() { |
| 93 | + let sched = scheds.pop(); |
| 94 | + let sched_cell = Cell(sched); |
| 95 | + let thread = do Thread::start { |
| 96 | + let mut sched = sched_cell.take(); |
| 97 | + sched.run(); |
| 98 | + }; |
| 99 | + |
| 100 | + threads.push(thread); |
| 101 | + } |
| 102 | + |
| 103 | + // Wait for schedulers |
| 104 | + let _threads = threads; |
| 105 | + } |
| 106 | +} |
| 107 | + |
49 | 108 | /// Test tasks will abort on failure instead of unwinding
|
50 | 109 | pub fn spawntask(f: ~fn()) {
|
51 | 110 | use super::sched::*;
|
|
0 commit comments