]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Restore IOLoop.current() when AsyncIOLoop exits.
authorBen Darnell <ben@bendarnell.com>
Thu, 30 Jul 2015 04:11:24 +0000 (00:11 -0400)
committerBen Darnell <ben@bendarnell.com>
Thu, 30 Jul 2015 04:11:24 +0000 (00:11 -0400)
Also make this process repeatable.

tornado/platform/asyncio.py
tornado/platform/twisted.py
tornado/test/ioloop_test.py

index 8f3dbff640008bf0871b8c6e6462fe14dd08740a..cfeadc98f55c1cbaa8e372c132eb335208d9ca5d 100644 (file)
@@ -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):
index 0bb8d54fe9863425cd45a127658e3e5c2f63fb13..272955a85c3cc2c834962510603d9f5bba3e733f 100644 (file)
@@ -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:
index 062d7225b069b6d59fb608f7e49689b518e5250a..c914b1c74bfb2226e1aee17ce28c587bd0d7b2b6 100644 (file)
@@ -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)