From 678b03165fe0155f93581d9d268aa6f6b6175345 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 10 Mar 2014 15:10:56 -0700 Subject: [PATCH] green: Fix a scheduler assertion on yielding This commit fixes a small bug in the green scheduler where a scheduler task calling `maybe_yield` would trip the assertion that `self.yield_check_count > 0` This behavior was seen when a scheduler task was scheduled many times successively, sending messages in a loop (via the channel `send` method), which in turn invokes `maybe_yield`. Yielding on a sched task doesn't make sense because as soon as it's done it will implicitly do a yield, and for this reason the yield check is just skipped if it's a sched task. I am unable to create a reliable test for this behavior, as there's no direct way to have control over the scheduler tasks. cc #12666, I discovered this when investigating that issue --- src/libgreen/sched.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/libgreen/sched.rs b/src/libgreen/sched.rs index a128ee4a25027..61b7089020f93 100644 --- a/src/libgreen/sched.rs +++ b/src/libgreen/sched.rs @@ -831,6 +831,20 @@ impl Scheduler { } pub fn maybe_yield(mut ~self, cur: ~GreenTask) { + // It's possible for sched tasks to possibly call this function, and it + // just means that they're likely sending on channels (which + // occasionally call this function). Sched tasks follow different paths + // when executing yield_now(), which may possibly trip the assertion + // below. For this reason, we just have sched tasks bail out soon. + // + // Sched tasks have no need to yield anyway because as soon as they + // return they'll yield to other threads by falling back to the event + // loop. Additionally, we completely control sched tasks, so we can make + // sure that they never execute more than enough code. + if cur.is_sched() { + return cur.put_with_sched(self) + } + // The number of times to do the yield check before yielding, chosen // arbitrarily. rtassert!(self.yield_check_count > 0);