diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2014-06-22 23:02:37 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2014-06-22 23:02:37 (GMT) |
commit | f328c7dc69da14766435d8608f89d81cd878bb4d (patch) | |
tree | e28c9941def58676945ff046468695a6f0a25561 | |
parent | 62511fd6d62ef53c1d3d050b478750efc5a7014c (diff) | |
download | cpython-f328c7dc69da14766435d8608f89d81cd878bb4d.zip cpython-f328c7dc69da14766435d8608f89d81cd878bb4d.tar.gz cpython-f328c7dc69da14766435d8608f89d81cd878bb4d.tar.bz2 |
asyncio, Tulip issue 171: BaseEventLoop.close() now raises an exception if the
event loop is running. You must first stop the event loop and then wait until
it stopped, before closing it.
-rw-r--r-- | Doc/library/asyncio-eventloop.rst | 2 | ||||
-rw-r--r-- | Lib/asyncio/base_events.py | 4 | ||||
-rw-r--r-- | Lib/asyncio/proactor_events.py | 2 | ||||
-rw-r--r-- | Lib/asyncio/selector_events.py | 2 | ||||
-rw-r--r-- | Lib/asyncio/unix_events.py | 2 | ||||
-rw-r--r-- | Lib/test/test_asyncio/test_events.py | 9 |
6 files changed, 18 insertions, 3 deletions
diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index e62f5ef..c242fc3 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -132,6 +132,8 @@ Run an event loop This clears the queues and shuts down the executor, but does not wait for the executor to finish. + The event loop must not be running. + This is idempotent and irreversible. No other methods should be called after this one. diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 2f7f197..42d8b0b 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -247,7 +247,11 @@ class BaseEventLoop(events.AbstractEventLoop): This clears the queues and shuts down the executor, but does not wait for the executor to finish. + + The event loop must not be running. """ + if self._running: + raise RuntimeError("cannot close a running event loop") if self._closed: return self._closed = True diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py index 757a22e..b76f69e 100644 --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -355,12 +355,12 @@ class BaseProactorEventLoop(base_events.BaseEventLoop): def close(self): if self.is_closed(): return + super().close() self._stop_accept_futures() self._close_self_pipe() self._proactor.close() self._proactor = None self._selector = None - super().close() def sock_recv(self, sock, n): return self._proactor.recv(sock, n) diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index a62a8e5..df64aec 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -57,11 +57,11 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop): def close(self): if self.is_closed(): return + super().close() self._close_self_pipe() if self._selector is not None: self._selector.close() self._selector = None - super().close() def _socketpair(self): raise NotImplementedError diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index acb327d..ad4c229 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -44,9 +44,9 @@ class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop): return socket.socketpair() def close(self): + super().close() for sig in list(self._signal_handlers): self.remove_signal_handler(sig) - super().close() def add_signal_handler(self, sig, callback, *args): """Add a handler for a signal. UNIX only. diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py index 37e45e1..020d123 100644 --- a/Lib/test/test_asyncio/test_events.py +++ b/Lib/test/test_asyncio/test_events.py @@ -1365,6 +1365,15 @@ class EventLoopTestsMixin: with self.assertRaises(RuntimeError): loop.add_writer(w, callback) + def test_close_running_event_loop(self): + @asyncio.coroutine + def close_loop(loop): + self.loop.close() + + coro = close_loop(self.loop) + with self.assertRaises(RuntimeError): + self.loop.run_until_complete(coro) + class SubprocessTestsMixin: |