@@ -38,12 +38,9 @@ pub struct Scheduler {
38
38
priv saved_context : Context ,
39
39
/// The currently executing task
40
40
priv current_task : Option < ~Task > ,
41
- /// A queue of jobs to perform immediately upon return from task
42
- /// context to scheduler context.
43
- /// XXX: This probably should be a single cleanup action and it
44
- /// should run after a context switch, not on return from the
45
- /// scheduler
46
- priv cleanup_jobs : ~[ CleanupJob ]
41
+ /// An action performed after a context switch on behalf of the
42
+ /// code running before the context switch
43
+ priv cleanup_job : Option < CleanupJob >
47
44
}
48
45
49
46
// XXX: Some hacks to put a &fn in Scheduler without borrowck
@@ -84,7 +81,7 @@ pub impl Scheduler {
84
81
stack_pool : StackPool :: new ( ) ,
85
82
saved_context : Context :: empty ( ) ,
86
83
current_task : None ,
87
- cleanup_jobs : ~ [ ]
84
+ cleanup_job : None
88
85
}
89
86
}
90
87
@@ -165,7 +162,7 @@ pub impl Scheduler {
165
162
assert ! ( self . current_task. is_none( ) ) ;
166
163
167
164
// Running tasks may have asked us to do some cleanup
168
- self . run_cleanup_jobs ( ) ;
165
+ self . run_cleanup_job ( ) ;
169
166
}
170
167
171
168
@@ -212,7 +209,7 @@ pub impl Scheduler {
212
209
Context :: swap ( last_task_context, sched_context) ;
213
210
}
214
211
215
- self . run_cleanup_jobs ( ) ;
212
+ self . run_cleanup_job ( ) ;
216
213
}
217
214
218
215
/// Switch directly to another task, without going through the scheduler.
@@ -233,29 +230,33 @@ pub impl Scheduler {
233
230
Context :: swap ( last_task_context, next_task_context) ;
234
231
}
235
232
236
- self . run_cleanup_jobs ( ) ;
233
+ self . run_cleanup_job ( ) ;
237
234
}
238
235
239
236
// * Other stuff
240
237
241
238
fn in_task_context ( & self ) -> bool { self . current_task . is_some ( ) }
242
239
243
240
fn enqueue_cleanup_job ( & mut self , job : CleanupJob ) {
244
- self . cleanup_jobs . unshift ( job) ;
241
+ assert ! ( self . cleanup_job. is_none( ) ) ;
242
+ self . cleanup_job = Some ( job) ;
245
243
}
246
244
247
- fn run_cleanup_jobs ( & mut self ) {
245
+ fn run_cleanup_job ( & mut self ) {
248
246
rtdebug ! ( "running cleanup jobs" ) ;
249
247
250
- while !self . cleanup_jobs . is_empty ( ) {
251
- match self . cleanup_jobs . pop ( ) {
252
- RescheduleTask ( task) => {
253
- // NB: Pushing to the *front* of the queue
254
- self . task_queue . push_front ( task) ;
255
- }
256
- RecycleTask ( task) => task. recycle ( & mut self . stack_pool ) ,
257
- GiveTask ( task, f) => ( f. to_fn ( ) ) ( self , task)
248
+ if self . cleanup_job . is_none ( ) {
249
+ return ;
250
+ }
251
+
252
+ let cleanup_job = self . cleanup_job . swap_unwrap ( ) ;
253
+ match cleanup_job {
254
+ RescheduleTask ( task) => {
255
+ // NB: Pushing to the *front* of the queue
256
+ self . task_queue . push_front ( task) ;
258
257
}
258
+ RecycleTask ( task) => task. recycle ( & mut self . stack_pool ) ,
259
+ GiveTask ( task, f) => ( f. to_fn ( ) ) ( self , task)
259
260
}
260
261
}
261
262
@@ -271,16 +272,15 @@ pub impl Scheduler {
271
272
fn get_contexts ( & mut self ) -> ( & ' self mut Context ,
272
273
Option < & ' self mut Context > ,
273
274
Option < & ' self mut Context > ) {
274
- let last_task = if !self . cleanup_jobs . is_empty ( ) {
275
- let last_job: & ' self mut CleanupJob = & mut self . cleanup_jobs [ 0 ] ;
276
- let last_task: & ' self Task = match last_job {
277
- & RescheduleTask ( ~ref task) => task,
278
- & RecycleTask ( ~ref task) => task,
279
- & GiveTask ( ~ref task, _) => task,
280
- } ;
281
- Some ( last_task)
282
- } else {
283
- None
275
+ let last_task = match self . cleanup_job {
276
+ Some ( RescheduleTask ( ~ref task) ) |
277
+ Some ( RecycleTask ( ~ref task) ) |
278
+ Some ( GiveTask ( ~ref task, _) ) => {
279
+ Some ( task)
280
+ }
281
+ None => {
282
+ None
283
+ }
284
284
} ;
285
285
// XXX: Pattern matching mutable pointers above doesn't work
286
286
// because borrowck thinks the three patterns are conflicting
@@ -329,7 +329,7 @@ pub impl Task {
329
329
// have asked us to do some cleanup.
330
330
let mut sched = ThreadLocalScheduler :: new ( ) ;
331
331
let sched = sched. get_scheduler ( ) ;
332
- sched. run_cleanup_jobs ( ) ;
332
+ sched. run_cleanup_job ( ) ;
333
333
334
334
start ( ) ;
335
335
0 commit comments