@@ -114,6 +114,8 @@ pub impl Scheduler {
114
114
} ;
115
115
116
116
fn wake_up ( ) {
117
+ let sched = Local :: take :: < Scheduler > ( ) ;
118
+ sched. resume_task_from_queue ( ) ;
117
119
}
118
120
}
119
121
@@ -127,8 +129,8 @@ pub impl Scheduler {
127
129
self . event_loop . callback ( resume_task_from_queue) ;
128
130
129
131
fn resume_task_from_queue ( ) {
130
- let scheduler = Local :: take :: < Scheduler > ( ) ;
131
- scheduler . resume_task_from_queue ( ) ;
132
+ let sched = Local :: take :: < Scheduler > ( ) ;
133
+ sched . resume_task_from_queue ( ) ;
132
134
}
133
135
}
134
136
@@ -606,4 +608,70 @@ mod test {
606
608
} ;
607
609
}
608
610
}
611
+
612
+ #[ test]
613
+ fn multithreading ( ) {
614
+ use clone:: Clone ;
615
+ use iter:: Times ;
616
+ use rt:: work_queue:: WorkQueue ;
617
+ use rt:: comm:: * ;
618
+ use container:: Container ;
619
+ use vec:: OwnedVector ;
620
+ use rt:: rtio:: RemoteCallback ;
621
+
622
+ do run_in_bare_thread {
623
+ let work_queue1 = WorkQueue :: new ( ) ;
624
+ let work_queue2 = work_queue1. clone ( ) ;
625
+
626
+ let loop1 = ~UvEventLoop :: new ( ) ;
627
+ let mut sched1 = ~Scheduler :: new ( loop1, work_queue1. clone ( ) ) ;
628
+ let handle1 = sched1. make_handle ( ) ;
629
+ let sched1_cell = Cell ( sched1) ;
630
+ let handle1_cell = Cell ( handle1) ;
631
+
632
+ let loop2 = ~UvEventLoop :: new ( ) ;
633
+ let mut sched2 = ~Scheduler :: new ( loop2, work_queue2. clone ( ) ) ;
634
+ let handle2 = sched2. make_handle ( ) ;
635
+ let sched2_cell = Cell ( sched2) ;
636
+ let handle2_cell = Cell ( handle2) ;
637
+
638
+ let _thread1 = do Thread :: start {
639
+ let mut sched1 = sched1_cell. take ( ) ;
640
+ sched1. run ( ) ;
641
+ } ;
642
+
643
+ let _thread2 = do Thread :: start {
644
+ let mut sched2 = sched2_cell. take ( ) ;
645
+ let handle1_cell = Cell ( handle1_cell. take ( ) ) ;
646
+ let handle2_cell = Cell ( handle2_cell. take ( ) ) ;
647
+
648
+ let task = ~do Coroutine :: new ( & mut sched2. stack_pool ) {
649
+ // Hold handles to keep the schedulers alive
650
+ let mut handle1 = handle1_cell. take ( ) ;
651
+ let mut handle2 = handle2_cell. take ( ) ;
652
+
653
+ let mut ports = ~[ ] ;
654
+ for 10 . times {
655
+ let ( port, chan) = oneshot( ) ;
656
+ let chan_cell = Cell ( chan) ;
657
+ do spawntask_later {
658
+ chan_cell. take( ) . send( ( ) ) ;
659
+ }
660
+ ports. push( port) ;
661
+
662
+ // Make sure the other scheduler is awake
663
+ handle1. remote. fire( ) ;
664
+ handle2. remote. fire( ) ;
665
+ }
666
+
667
+ while !ports. is_empty( ) {
668
+ ports. pop( ) . recv( ) ;
669
+ }
670
+ } ;
671
+
672
+ sched2. enqueue_task( task) ;
673
+ sched2. run( ) ;
674
+ } ;
675
+ }
676
+ }
609
677
}
0 commit comments