Commit f328c7dc authored by Victor Stinner's avatar Victor Stinner

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.
parent 62511fd6
......@@ -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.
......
......@@ -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
......
......@@ -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)
......
......@@ -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
......
......@@ -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.
......
......@@ -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:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment