std::rt: Don't allow schedulers to exit before handling all messages
Every time run_sched_once performs a 'scheduling action' it needs to guarantee that it runs at least one more time, so enqueue another run_sched_once callback. The primary reason it needs to do this is because not all async callbacks are guaranteed to run, it's only guaranteed that *a* callback will run after enqueing one - some may get dropped. At the moment this means we wastefully create lots of callbacks to ensure that there will *definitely* be a callback queued up to continue running the scheduler. The logic really needs to be tightened up here.
This commit is contained in:
parent
f0f7e1b3fc
commit
a27f339cb4
@ -172,6 +172,10 @@ impl Scheduler {
|
||||
|
||||
rtdebug!("stopping scheduler %u", stask.sched.get_ref().sched_id());
|
||||
|
||||
// Should not have any messages
|
||||
let message = stask.sched.get_mut_ref().message_queue.pop();
|
||||
assert!(message.is_none());
|
||||
|
||||
stask.destroyed = true;
|
||||
}
|
||||
|
||||
@ -336,11 +340,14 @@ impl Scheduler {
|
||||
match this.message_queue.pop() {
|
||||
Some(PinnedTask(task)) => {
|
||||
let mut task = task;
|
||||
this.event_loop.callback(Scheduler::run_sched_once);
|
||||
task.give_home(Sched(this.make_handle()));
|
||||
this.resume_task_immediately(task);
|
||||
return None;
|
||||
}
|
||||
Some(TaskFromFriend(task)) => {
|
||||
this.event_loop.callback(Scheduler::run_sched_once);
|
||||
rtdebug!("got a task from a friend. lovely!");
|
||||
return this.sched_schedule_task(task);
|
||||
}
|
||||
Some(Wake) => {
|
||||
@ -395,6 +402,7 @@ impl Scheduler {
|
||||
/// Take a non-homed task we aren't allowed to run here and send
|
||||
/// it to the designated friend scheduler to execute.
|
||||
fn send_to_friend(&mut self, task: ~Task) {
|
||||
rtdebug!("sending a task to friend");
|
||||
match self.friend_handle {
|
||||
Some(ref mut handle) => {
|
||||
handle.send(TaskFromFriend(task));
|
||||
@ -426,12 +434,14 @@ impl Scheduler {
|
||||
Scheduler::send_task_home(task);
|
||||
return Some(this);
|
||||
} else {
|
||||
this.event_loop.callback(Scheduler::run_sched_once);
|
||||
task.give_home(Sched(home_handle));
|
||||
this.resume_task_immediately(task);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
AnySched if this.run_anything => {
|
||||
this.event_loop.callback(Scheduler::run_sched_once);
|
||||
task.give_home(AnySched);
|
||||
this.resume_task_immediately(task);
|
||||
return None;
|
||||
|
Loading…
x
Reference in New Issue
Block a user