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