diff options
author | Yury Selivanov <yselivanov@sprymix.com> | 2014-09-25 16:07:56 (GMT) |
---|---|---|
committer | Yury Selivanov <yselivanov@sprymix.com> | 2014-09-25 16:07:56 (GMT) |
commit | 592ada9b4b08ad57037e365b9c462d71c96e4453 (patch) | |
tree | abe659c0d56cf1446fb2a0eaa3a557f3a55c6e40 /Lib/asyncio/events.py | |
parent | 8c0e0ab767f0d6f8395d8c317b08977563b70d41 (diff) | |
download | cpython-592ada9b4b08ad57037e365b9c462d71c96e4453.zip cpython-592ada9b4b08ad57037e365b9c462d71c96e4453.tar.gz cpython-592ada9b4b08ad57037e365b9c462d71c96e4453.tar.bz2 |
asyncio: Improve canceled timer handles cleanup. Closes issue #22448.
Patch by Joshua Moore-Oliva.
Diffstat (limited to 'Lib/asyncio/events.py')
-rw-r--r-- | Lib/asyncio/events.py | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/Lib/asyncio/events.py b/Lib/asyncio/events.py index b7cc351..806218f 100644 --- a/Lib/asyncio/events.py +++ b/Lib/asyncio/events.py @@ -105,14 +105,15 @@ class Handle: return '<%s>' % ' '.join(info) def cancel(self): - self._cancelled = True - if self._loop.get_debug(): - # Keep a representation in debug mode to keep callback and - # parameters. For example, to log the warning "Executing <Handle - # ...> took 2.5 second" - self._repr = repr(self) - self._callback = None - self._args = None + if not self._cancelled: + self._cancelled = True + if self._loop.get_debug(): + # Keep a representation in debug mode to keep callback and + # parameters. For example, to log the warning + # "Executing <Handle...> took 2.5 second" + self._repr = repr(self) + self._callback = None + self._args = None def _run(self): try: @@ -134,7 +135,7 @@ class Handle: class TimerHandle(Handle): """Object returned by timed callback registration methods.""" - __slots__ = ['_when'] + __slots__ = ['_scheduled', '_when'] def __init__(self, when, callback, args, loop): assert when is not None @@ -142,6 +143,7 @@ class TimerHandle(Handle): if self._source_traceback: del self._source_traceback[-1] self._when = when + self._scheduled = False def _repr_info(self): info = super()._repr_info() @@ -180,6 +182,11 @@ class TimerHandle(Handle): equal = self.__eq__(other) return NotImplemented if equal is NotImplemented else not equal + def cancel(self): + if not self._cancelled: + self._loop._timer_handle_cancelled(self) + super().cancel() + class AbstractServer: """Abstract server returned by create_server().""" @@ -238,6 +245,10 @@ class AbstractEventLoop: # Methods scheduling callbacks. All these return Handles. + def _timer_handle_cancelled(self, handle): + """Notification that a TimerHandle has been cancelled.""" + raise NotImplementedError + def call_soon(self, callback, *args): return self.call_later(0, callback, *args) |