diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2014-06-10 08:23:10 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2014-06-10 08:23:10 (GMT) |
commit | bb2fc5b2a58993c80ee81f10fe463039520a4162 (patch) | |
tree | 7f072c58fe93ed3fec34e99c5bb642e81f68be52 /Lib/asyncio/base_events.py | |
parent | 15386652bfc57721d52e00e43a0e2ed66724995d (diff) | |
download | cpython-bb2fc5b2a58993c80ee81f10fe463039520a4162.zip cpython-bb2fc5b2a58993c80ee81f10fe463039520a4162.tar.gz cpython-bb2fc5b2a58993c80ee81f10fe463039520a4162.tar.bz2 |
Issue #21326: Add a new is_closed() method to asyncio.BaseEventLoop
Add BaseEventLoop._closed attribute and use it to check if the event loop was
closed or not, instead of checking different attributes in each subclass of
BaseEventLoop.
run_forever() and run_until_complete() methods now raise a RuntimeError('Event loop is
closed') exception if the event loop was closed.
BaseProactorEventLoop.close() now also cancels "accept futures".
Diffstat (limited to 'Lib/asyncio/base_events.py')
-rw-r--r-- | Lib/asyncio/base_events.py | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 1c7073c..5ee21d1 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -119,6 +119,7 @@ class Server(events.AbstractServer): class BaseEventLoop(events.AbstractEventLoop): def __init__(self): + self._closed = False self._ready = collections.deque() self._scheduled = [] self._default_executor = None @@ -128,6 +129,11 @@ class BaseEventLoop(events.AbstractEventLoop): self._exception_handler = None self._debug = False + def __repr__(self): + return ('<%s running=%s closed=%s debug=%s>' + % (self.__class__.__name__, self.is_running(), + self.is_closed(), self.get_debug())) + def _make_socket_transport(self, sock, protocol, waiter=None, *, extra=None, server=None): """Create socket transport.""" @@ -173,8 +179,13 @@ class BaseEventLoop(events.AbstractEventLoop): """Process selector events.""" raise NotImplementedError + def _check_closed(self): + if self._closed: + raise RuntimeError('Event loop is closed') + def run_forever(self): """Run until stop() is called.""" + self._check_closed() if self._running: raise RuntimeError('Event loop is running.') self._running = True @@ -198,6 +209,7 @@ class BaseEventLoop(events.AbstractEventLoop): Return the Future's result, or raise its exception. """ + self._check_closed() future = tasks.async(future, loop=self) future.add_done_callback(_raise_stop_error) self.run_forever() @@ -222,6 +234,9 @@ class BaseEventLoop(events.AbstractEventLoop): This clears the queues and shuts down the executor, but does not wait for the executor to finish. """ + if self._closed: + return + self._closed = True self._ready.clear() self._scheduled.clear() executor = self._default_executor @@ -229,6 +244,10 @@ class BaseEventLoop(events.AbstractEventLoop): self._default_executor = None executor.shutdown(wait=False) + def is_closed(self): + """Returns True if the event loop was closed.""" + return self._closed + def is_running(self): """Returns running status of event loop.""" return self._running |