@@ -68,7 +68,10 @@ pub struct Scheduler {
68
68
priv cleanup_job : Option < CleanupJob > ,
69
69
metrics : SchedMetrics ,
70
70
/// Should this scheduler run any task, or only pinned tasks?
71
- run_anything : bool
71
+ run_anything : bool ,
72
+ /// If the scheduler shouldn't run some tasks, a friend to send
73
+ /// them to.
74
+ friend_handle : Option < SchedHandle >
72
75
}
73
76
74
77
pub struct SchedHandle {
@@ -80,7 +83,8 @@ pub struct SchedHandle {
80
83
pub enum SchedMessage {
81
84
Wake ,
82
85
Shutdown ,
83
- PinnedTask ( ~Task )
86
+ PinnedTask ( ~Task ) ,
87
+ TaskFromFriend ( ~Task )
84
88
}
85
89
86
90
enum CleanupJob {
@@ -97,7 +101,7 @@ impl Scheduler {
97
101
sleeper_list : SleeperList )
98
102
-> Scheduler {
99
103
100
- Scheduler :: new_special ( event_loop, work_queue, sleeper_list, true )
104
+ Scheduler :: new_special ( event_loop, work_queue, sleeper_list, true , None )
101
105
102
106
}
103
107
@@ -106,7 +110,8 @@ impl Scheduler {
106
110
pub fn new_special ( event_loop : ~EventLoopObject ,
107
111
work_queue : WorkQueue < ~Task > ,
108
112
sleeper_list : SleeperList ,
109
- run_anything : bool )
113
+ run_anything : bool ,
114
+ friend : Option < SchedHandle > )
110
115
-> Scheduler {
111
116
112
117
Scheduler {
@@ -120,7 +125,8 @@ impl Scheduler {
120
125
sched_task : None ,
121
126
cleanup_job : None ,
122
127
metrics : SchedMetrics :: new ( ) ,
123
- run_anything : run_anything
128
+ run_anything : run_anything,
129
+ friend_handle : friend
124
130
}
125
131
}
126
132
@@ -327,6 +333,10 @@ impl Scheduler {
327
333
this. resume_task_immediately ( task) ;
328
334
return None ;
329
335
}
336
+ Some ( TaskFromFriend ( task) ) => {
337
+ this. resume_task_immediately ( task) ;
338
+ return None ;
339
+ }
330
340
Some ( Wake ) => {
331
341
this. sleepy = false ;
332
342
return Some ( this) ;
@@ -376,6 +386,19 @@ impl Scheduler {
376
386
}
377
387
}
378
388
389
+ /// Take a non-homed task we aren't allowed to run here and send
390
+ /// it to the designated friend scheduler to execute.
391
+ fn send_to_friend ( & mut self , task : ~Task ) {
392
+ match self . friend_handle {
393
+ Some ( ref mut handle) => {
394
+ handle. send ( TaskFromFriend ( task) ) ;
395
+ }
396
+ None => {
397
+ rtabort ! ( "tried to send task to a friend but scheduler has no friends" ) ;
398
+ }
399
+ }
400
+ }
401
+
379
402
// Resume a task from the queue - but also take into account that
380
403
// it might not belong here.
381
404
@@ -409,7 +432,8 @@ impl Scheduler {
409
432
}
410
433
AnySched => {
411
434
task. give_home ( AnySched ) ;
412
- this. enqueue_task ( task) ;
435
+ // this.enqueue_task(task);
436
+ this. send_to_friend ( task) ;
413
437
return Some ( this) ;
414
438
}
415
439
}
@@ -816,12 +840,15 @@ mod test {
816
840
817
841
let normal_handle = Cell :: new ( normal_sched. make_handle ( ) ) ;
818
842
843
+ let friend_handle = normal_sched. make_handle ( ) ;
844
+
819
845
// Our special scheduler
820
846
let mut special_sched = ~Scheduler :: new_special (
821
847
~UvEventLoop :: new ( ) ,
822
848
work_queue. clone ( ) ,
823
849
sleepers. clone ( ) ,
824
- false ) ;
850
+ false ,
851
+ Some ( friend_handle) ) ;
825
852
826
853
let special_handle = Cell :: new ( special_sched. make_handle ( ) ) ;
827
854
0 commit comments