summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2014-06-22 23:02:37 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2014-06-22 23:02:37 (GMT)
commitf328c7dc69da14766435d8608f89d81cd878bb4d (patch)
treee28c9941def58676945ff046468695a6f0a25561
parent62511fd6d62ef53c1d3d050b478750efc5a7014c (diff)
downloadcpython-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.rst2
-rw-r--r--Lib/asyncio/base_events.py4
-rw-r--r--Lib/asyncio/proactor_events.py2
-rw-r--r--Lib/asyncio/selector_events.py2
-rw-r--r--Lib/asyncio/unix_events.py2
-rw-r--r--Lib/test/test_asyncio/test_events.py9
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: