mirror of
https://github.com/Klipper3d/klipper.git
synced 2026-05-06 17:57:17 +02:00
reactor: Always create new greenlets from main process
If a greenlet is created from a greenlet then it seems the Python interpreter will increment its call depth counter and that can eventually lead to a RecursionError exception being raised. To avoid this issue, switch back to the main run() instance if a new greenlet needs to be created. Signed-off-by: Timofey Titovets <nefelim4ag@gmail.com> Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
committed by
KevinOConnor
parent
1370cf5c18
commit
51ceda9ede
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user