@@ -80,7 +80,7 @@ pub struct Scheduler {
80
80
/// A fast XorShift rng for scheduler use
81
81
rng : XorShiftRng ,
82
82
/// A toggleable idle callback
83
- idle_callback : ~PausibleIdleCallback
83
+ idle_callback : Option < ~PausibleIdleCallback >
84
84
}
85
85
86
86
impl Scheduler {
@@ -107,9 +107,6 @@ impl Scheduler {
107
107
friend : Option < SchedHandle > )
108
108
-> Scheduler {
109
109
110
- let mut event_loop = event_loop;
111
- let idle_callback = event_loop. pausible_idle_callback ( ) ;
112
-
113
110
Scheduler {
114
111
sleeper_list : sleeper_list,
115
112
message_queue : MessageQueue :: new ( ) ,
@@ -125,7 +122,7 @@ impl Scheduler {
125
122
run_anything : run_anything,
126
123
friend_handle : friend,
127
124
rng : XorShiftRng :: new ( ) ,
128
- idle_callback : idle_callback
125
+ idle_callback : None
129
126
}
130
127
}
131
128
@@ -140,6 +137,9 @@ impl Scheduler {
140
137
141
138
let mut this = self ;
142
139
140
+ // Build an Idle callback.
141
+ this. idle_callback = Some ( this. event_loop . pausible_idle_callback ( ) ) ;
142
+
143
143
// Initialize the TLS key.
144
144
local_ptr:: init_tls_key ( ) ;
145
145
@@ -153,7 +153,7 @@ impl Scheduler {
153
153
// Before starting our first task, make sure the idle callback
154
154
// is active. As we do not start in the sleep state this is
155
155
// important.
156
- this. idle_callback . start ( Scheduler :: run_sched_once) ;
156
+ this. idle_callback . get_mut_ref ( ) . start ( Scheduler :: run_sched_once) ;
157
157
158
158
// Now, as far as all the scheduler state is concerned, we are
159
159
// inside the "scheduler" context. So we can act like the
@@ -169,6 +169,12 @@ impl Scheduler {
169
169
rtdebug ! ( "starting scheduler %u" , sched. sched_id( ) ) ;
170
170
sched. run ( ) ;
171
171
172
+ // Close the idle callback.
173
+ let mut sched = Local :: take :: < Scheduler > ( ) ;
174
+ sched. idle_callback . get_mut_ref ( ) . close ( ) ;
175
+ // Make one go through the loop to run the close callback.
176
+ sched. run ( ) ;
177
+
172
178
// Now that we are done with the scheduler, clean up the
173
179
// scheduler task. Do so by removing it from TLS and manually
174
180
// cleaning up the memory it uses. As we didn't actually call
@@ -182,9 +188,6 @@ impl Scheduler {
182
188
let message = stask. sched . get_mut_ref ( ) . message_queue . pop ( ) ;
183
189
assert ! ( message. is_none( ) ) ;
184
190
185
- // Close the idle callback.
186
- stask. sched . get_mut_ref ( ) . idle_callback . close ( ) ;
187
-
188
191
stask. destroyed = true ;
189
192
}
190
193
@@ -230,7 +233,7 @@ impl Scheduler {
230
233
231
234
// Assume that we need to continue idling unless we reach the
232
235
// end of this function without performing an action.
233
- sched. idle_callback . resume ( ) ;
236
+ sched. idle_callback . get_mut_ref ( ) . resume ( ) ;
234
237
235
238
// First we check for scheduler messages, these are higher
236
239
// priority than regular tasks.
@@ -257,12 +260,12 @@ impl Scheduler {
257
260
let handle = sched. make_handle ( ) ;
258
261
sched. sleeper_list . push ( handle) ;
259
262
// Since we are sleeping, deactivate the idle callback.
260
- sched. idle_callback . pause ( ) ;
263
+ sched. idle_callback . get_mut_ref ( ) . pause ( ) ;
261
264
} else {
262
265
rtdebug ! ( "not sleeping, already doing so or no_sleep set" ) ;
263
266
// We may not be sleeping, but we still need to deactivate
264
267
// the idle callback.
265
- sched. idle_callback . pause ( ) ;
268
+ sched. idle_callback . get_mut_ref ( ) . pause ( ) ;
266
269
}
267
270
268
271
// Finished a cycle without using the Scheduler. Place it back
@@ -461,7 +464,7 @@ impl Scheduler {
461
464
462
465
// We push the task onto our local queue clone.
463
466
this. work_queue . push ( task) ;
464
- this. idle_callback . resume ( ) ;
467
+ this. idle_callback . get_mut_ref ( ) . resume ( ) ;
465
468
466
469
// We've made work available. Notify a
467
470
// sleeping scheduler.
0 commit comments