diff --git a/eventlet/greenthread.py b/eventlet/greenthread.py index 6e99b60..96b7fff 100644 --- a/eventlet/greenthread.py +++ b/eventlet/greenthread.py @@ -258,5 +258,6 @@ def kill(g, *throw_args): current = getcurrent() if current is not hub.greenlet: # arrange to wake the caller back up immediately + hub.ensure_greenlet() hub.schedule_call_global(0, current.switch) g.throw(*throw_args) diff --git a/eventlet/hubs/hub.py b/eventlet/hubs/hub.py index a224893..03bb817 100644 --- a/eventlet/hubs/hub.py +++ b/eventlet/hubs/hub.py @@ -157,6 +157,17 @@ class BaseHub(object): except Exception, e: self.squelch_generic_exception(sys.exc_info()) + def ensure_greenlet(self): + if self.greenlet.dead: + # create new greenlet sharing same parent as original + new = greenlet.greenlet(self.run, self.greenlet.parent) + # need to assign as parent of old greenlet + # for those greenlets that are currently + # children of the dead hub and may subsequently + # exit without further switching to hub. + self.greenlet.parent = new + self.greenlet = new + def switch(self): cur = greenlet.getcurrent() assert cur is not self.greenlet, 'Cannot switch to MAINLOOP from MAINLOOP' @@ -166,8 +177,7 @@ class BaseHub(object): switch_out() except: self.squelch_generic_exception(sys.exc_info()) - if self.greenlet.dead: - self.greenlet = greenlet.greenlet(self.run) + self.ensure_greenlet() try: if self.greenlet.parent is not cur: cur.parent = self.greenlet