From 16ea195b26a04a64c744ed1d4a38b9a6ad6e1cfd Mon Sep 17 00:00:00 2001 From: Edward George Date: Sat, 11 Aug 2012 13:27:28 +0100 Subject: [PATCH] ensure that new hub greenlet is parent of old, dead hub greenlet. also, ensure this happens when eventlet.greenthread.kill() is used. --- eventlet/greenthread.py | 1 + eventlet/hubs/hub.py | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) 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