From: Ben Darnell Date: Thu, 30 Jul 2015 04:11:24 +0000 (-0400) Subject: Restore IOLoop.current() when AsyncIOLoop exits. X-Git-Tag: v4.3.0b1~69 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8943ee06df4ad850a9e4fd2aec85c537e31040af;p=thirdparty%2Ftornado.git Restore IOLoop.current() when AsyncIOLoop exits. Also make this process repeatable. --- diff --git a/tornado/platform/asyncio.py b/tornado/platform/asyncio.py index 8f3dbff64..cfeadc98f 100644 --- a/tornado/platform/asyncio.py +++ b/tornado/platform/asyncio.py @@ -35,7 +35,6 @@ class BaseAsyncIOLoop(IOLoop): super(BaseAsyncIOLoop, self).initialize(**kwargs) self.asyncio_loop = asyncio_loop self.close_loop = close_loop - self.asyncio_loop.call_soon(self.make_current) # Maps fd to (fileobj, handler function) pair (as in IOLoop.add_handler) self.handlers = {} # Set of fds listening for reads/writes @@ -105,8 +104,16 @@ class BaseAsyncIOLoop(IOLoop): handler_func(fileobj, events) def start(self): - self._setup_logging() - self.asyncio_loop.run_forever() + old_current = IOLoop.current(instance=False) + try: + self._setup_logging() + self.make_current() + self.asyncio_loop.run_forever() + finally: + if old_current is None: + IOLoop.clear_current() + else: + old_current.make_current() def stop(self): self.asyncio_loop.stop() @@ -140,8 +147,14 @@ class AsyncIOMainLoop(BaseAsyncIOLoop): class AsyncIOLoop(BaseAsyncIOLoop): def initialize(self, **kwargs): - super(AsyncIOLoop, self).initialize(asyncio.new_event_loop(), - close_loop=True, **kwargs) + loop = asyncio.new_event_loop() + try: + super(AsyncIOLoop, self).initialize(loop, close_loop=True, **kwargs) + except Exception: + # If initialize() does not succeed (taking ownership of the loop), + # we have to close it. + loop.close() + raise def to_tornado_future(asyncio_future): diff --git a/tornado/platform/twisted.py b/tornado/platform/twisted.py index 0bb8d54fe..272955a85 100644 --- a/tornado/platform/twisted.py +++ b/tornado/platform/twisted.py @@ -423,7 +423,6 @@ class TwistedIOLoop(tornado.ioloop.IOLoop): reactor = twisted.internet.reactor self.reactor = reactor self.fds = {} - self.reactor.callWhenRunning(self.make_current) def close(self, all_fds=False): fds = self.fds @@ -480,6 +479,7 @@ class TwistedIOLoop(tornado.ioloop.IOLoop): old_current = IOLoop.current(instance=False) try: self._setup_logging() + self.make_current() self.reactor.run() finally: if old_current is None: diff --git a/tornado/test/ioloop_test.py b/tornado/test/ioloop_test.py index 062d7225b..c914b1c74 100644 --- a/tornado/test/ioloop_test.py +++ b/tornado/test/ioloop_test.py @@ -429,15 +429,18 @@ class TestIOLoopCurrent(unittest.TestCase): self.io_loop = IOLoop(make_current=False) # The new IOLoop is not initially made current. self.assertIsNone(IOLoop.current(instance=False)) - def f(): - # But it is current after it is started. - self.current_io_loop = IOLoop.current() - self.io_loop.stop() - self.io_loop.add_callback(f) - self.io_loop.start() - self.assertIs(self.current_io_loop, self.io_loop) - # Now that the loop is stopped, it is no longer current. - self.assertIsNone(IOLoop.current(instance=False)) + # Starting the IOLoop makes it current, and stopping the loop + # makes it non-current. This process is repeatable. + for i in range(3): + def f(): + self.current_io_loop = IOLoop.current() + self.io_loop.stop() + self.io_loop.add_callback(f) + self.io_loop.start() + self.assertIs(self.current_io_loop, self.io_loop) + # Now that the loop is stopped, it is no longer current. + self.assertIsNone(IOLoop.current(instance=False)) + def test_force_current(self): self.io_loop = IOLoop(make_current=True)