ensure that new hub greenlet is parent of old, dead hub greenlet.

also, ensure this happens when eventlet.greenthread.kill() is used.
This commit is contained in:
Edward George
2012-08-11 13:27:28 +01:00
parent 2055061aaa
commit 16ea195b26
2 changed files with 13 additions and 2 deletions

View File

@@ -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)

View File

@@ -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