diff --git a/klippy/reactor.py b/klippy/reactor.py index aba4c06f5..aab57d992 100644 --- a/klippy/reactor.py +++ b/klippy/reactor.py @@ -231,21 +231,22 @@ class SelectReactor: return self._sys_pause(waketime) if self._prevent_pause_count: self.verify_can_pause() + # Determine if this greenlet is the main dispatch greenlet g = greenlet.getcurrent() if g is not self._g_dispatch: - # Switch to _check_timers (via g.timer.callback return) + # This greenlet has called pause() before and has a timer setup, + # so switch to _check_timers (via g.timer.callback return) return self._g_dispatch.switch(waketime) - # Pausing the dispatch greenlet - prepare a new greenlet to do dispatch - if self._greenlets: - g_next = self._greenlets.pop() - else: - g_next = ReactorGreenlet(run=self._dispatch_loop) - self._all_greenlets.append(g_next) - g_next.parent = g.parent + # Pausing the dispatch greenlet - setup timer to resume this greenlet g.timer = self.register_timer(g.switch, waketime) self._next_timer = self.NOW - # Switch to _dispatch_loop (via _end_greenlet or direct) - eventtime = g_next.switch() + if self._greenlets: + # Switch to _end_greenlet to activate cached dispatch greenlet + g_next = self._greenlets.pop() + eventtime = g_next.switch() + else: + # No cached greenlets, switch to run() to create new dispatcher + eventtime = g.parent.switch() # This greenlet activated from g.timer.callback (via _check_timers) return eventtime def _end_greenlet(self, g_old): @@ -323,9 +324,10 @@ class SelectReactor: self._setup_async_callbacks() self._process = True self._prevent_pause_count = 0 - g_next = ReactorGreenlet(run=self._dispatch_loop) - self._all_greenlets.append(g_next) - g_next.switch() + while self._process: + g_next = ReactorGreenlet(run=self._dispatch_loop) + self._all_greenlets.append(g_next) + g_next.switch() def end(self): self._process = False def finalize(self):