diff --git a/tornado/test/ioloop_test.py b/tornado/test/ioloop_test.py index 110158d1..7eb7594f 100644 --- a/tornado/test/ioloop_test.py +++ b/tornado/test/ioloop_test.py @@ -334,6 +334,33 @@ class TestIOLoop(AsyncTestCase): with ExpectLog(app_log, "Exception in callback"): self.wait() + @skipIfNonUnix + def test_remove_handler_from_handler(self): + # Create two sockets with simultaneous read events. + client, server = socket.socketpair() + try: + client.send(b'abc') + server.send(b'abc') + + # After reading from one fd, remove the other from the IOLoop. + chunks = [] + def handle_read(fd, events): + chunks.append(fd.recv(1024)) + if fd is client: + self.io_loop.remove_handler(server) + else: + self.io_loop.remove_handler(client) + self.io_loop.add_handler(client, handle_read, self.io_loop.READ) + self.io_loop.add_handler(server, handle_read, self.io_loop.READ) + self.io_loop.call_later(0.01, self.stop) + self.wait() + + # Only one fd was read; the other was cleanly removed. + self.assertEqual(chunks, [b'abc']) + finally: + client.close() + server.close() + # Deliberately not a subclass of AsyncTestCase so the IOLoop isn't # automatically set as current.