@@ -171,7 +171,7 @@ impl Scheduler {
171
171
172
172
// Take a main task to run, and a scheduler to run it in. Create a
173
173
// scheduler task and bootstrap into it.
174
- pub fn bootstrap ( mut ~self , task : ~ GreenTask ) {
174
+ pub fn bootstrap ( mut ~self ) {
175
175
176
176
// Build an Idle callback.
177
177
let cb = ~SchedRunner as ~Callback ;
@@ -187,18 +187,11 @@ impl Scheduler {
187
187
self . idle_callback . get_mut_ref ( ) . resume ( ) ;
188
188
189
189
// Now, as far as all the scheduler state is concerned, we are inside
190
- // the "scheduler" context. So we can act like the scheduler and resume
191
- // the provided task. Let it think that the currently running task is
192
- // actually the sched_task so it knows where to squirrel it away.
193
- let mut sched_task = self . resume_task_immediately ( sched_task, task) ;
194
-
195
- // Now we are back in the scheduler context, having
196
- // successfully run the input task. Start by running the
197
- // scheduler. Grab it out of TLS - performing the scheduler
198
- // action will have given it away.
199
- let sched = sched_task. sched . take_unwrap ( ) ;
200
- rtdebug ! ( "starting scheduler {}" , sched. sched_id( ) ) ;
201
- let mut sched_task = sched. run ( sched_task) ;
190
+ // the "scheduler" context. The scheduler immediately hands over control
191
+ // to the event loop, and this will only exit once the event loop no
192
+ // longer has any references (handles or I/O objects).
193
+ rtdebug ! ( "starting scheduler {}" , self . sched_id( ) ) ;
194
+ let mut sched_task = self . run ( sched_task) ;
202
195
203
196
// Close the idle callback.
204
197
let mut sched = sched_task. sched . take_unwrap ( ) ;
@@ -548,7 +541,10 @@ impl Scheduler {
548
541
// We push the task onto our local queue clone.
549
542
assert ! ( !task. is_sched( ) ) ;
550
543
self . work_queue . push ( task) ;
551
- self . idle_callback . get_mut_ref ( ) . resume ( ) ;
544
+ match self . idle_callback {
545
+ Some ( ref mut idle) => idle. resume ( ) ,
546
+ None => { } // allow enqueuing before the scheduler starts
547
+ }
552
548
553
549
// We've made work available. Notify a
554
550
// sleeping scheduler.
@@ -1176,25 +1172,21 @@ mod test {
1176
1172
let mut sh = special_handle;
1177
1173
sh. send ( Shutdown ) ;
1178
1174
} ;
1179
-
1175
+ normal_sched . enqueue_task ( normal_task ) ;
1180
1176
1181
1177
let special_task = do GreenTask :: new ( & mut special_sched. stack_pool ,
1182
1178
None ) {
1183
1179
run ( task1) ;
1184
1180
run ( task3) ;
1185
1181
chan. send ( ( ) ) ;
1186
1182
} ;
1187
-
1183
+ special_sched . enqueue_task ( special_task ) ;
1188
1184
1189
1185
let normal_sched = normal_sched;
1190
- let normal_thread = do Thread :: start {
1191
- normal_sched. bootstrap ( normal_task) ;
1192
- } ;
1186
+ let normal_thread = do Thread :: start { normal_sched. bootstrap ( ) } ;
1193
1187
1194
1188
let special_sched = special_sched;
1195
- let special_thread = do Thread :: start {
1196
- special_sched. bootstrap ( special_task) ;
1197
- } ;
1189
+ let special_thread = do Thread :: start { special_sched. bootstrap ( ) } ;
1198
1190
1199
1191
normal_thread. join ( ) ;
1200
1192
special_thread. join ( ) ;
0 commit comments