Call cancel timers on the way out of the main greenlet_body, since that timer can't possibly resume the greenlet since it's going to be dead once that function returns.
This commit is contained in:
@@ -265,6 +265,7 @@ def greenlet_body(value, exc):
|
||||
|
||||
Greenlets using this body must be greenlib.switch()'ed to
|
||||
"""
|
||||
from eventlet import api
|
||||
if exc is not None:
|
||||
if isinstance(exc, tuple):
|
||||
raise exc[0], exc[1], exc[2]
|
||||
@@ -282,12 +283,14 @@ def greenlet_body(value, exc):
|
||||
except AttributeError:
|
||||
greenlet_id = 1
|
||||
_threadlocal.next_greenlet_id = itertools.count(2)
|
||||
greenlets[greenlet.getcurrent()] = {'greenlet_id': greenlet_id}
|
||||
cur = greenlet.getcurrent()
|
||||
greenlets[cur] = {'greenlet_id': greenlet_id}
|
||||
try:
|
||||
return cb(*args)
|
||||
finally:
|
||||
_greenlet_context_call('finalize')
|
||||
greenlets.pop(greenlet.getcurrent(), None)
|
||||
greenlets.pop(cur, None)
|
||||
api.get_hub().cancel_timers(cur, quiet=True)
|
||||
|
||||
|
||||
class SwitchingToDeadGreenlet(RuntimeError):
|
||||
|
@@ -283,7 +283,7 @@ class BaseHub(object):
|
||||
pass
|
||||
del t[:last]
|
||||
|
||||
def cancel_timers(self, greenlet):
|
||||
def cancel_timers(self, greenlet, quiet=False):
|
||||
if greenlet not in self.timers_by_greenlet:
|
||||
return
|
||||
for timer in self.timers_by_greenlet[greenlet]:
|
||||
@@ -292,6 +292,6 @@ class BaseHub(object):
|
||||
## actually eventlet's silly way of specifying whether
|
||||
## a coroutine is "ready to run" or not.
|
||||
timer.cancel()
|
||||
if _g_debug:
|
||||
if _g_debug and not quiet:
|
||||
print 'Hub cancelling left-over timer %s' % timer
|
||||
del self.timers_by_greenlet[greenlet]
|
||||
|
Reference in New Issue
Block a user