From a27f339cb4480e723aa7e06070683966d026d1ae Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sat, 3 Aug 2013 23:29:21 -0700 Subject: [PATCH] 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. --- src/libstd/rt/sched.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs index 18cfeade157d..a5c8abc2a6c0 100644 --- a/src/libstd/rt/sched.rs +++ b/src/libstd/rt/sched.rs @@ -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;