From: Ben Darnell Date: Sat, 18 Jan 2014 21:04:49 +0000 (-0500) Subject: Pass the correct file object to IOLoop handler functions. X-Git-Tag: v4.0.0b1~145 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0416a6894cde3c4bb82580cce123f0baa2187729;p=thirdparty%2Ftornado.git Pass the correct file object to IOLoop handler functions. --- diff --git a/tornado/ioloop.py b/tornado/ioloop.py index da3d789ee..c2c520e30 100644 --- a/tornado/ioloop.py +++ b/tornado/ioloop.py @@ -741,7 +741,8 @@ class PollIOLoop(IOLoop): while self._events: fd, events = self._events.popitem() try: - self._handlers[fd][1](fd, events) + fd_obj, handler_func = self._handlers[fd] + handler_func(fd_obj, events) except (OSError, IOError) as e: if e.args[0] == errno.EPIPE: # Happens when the client closes the connection @@ -750,6 +751,7 @@ class PollIOLoop(IOLoop): self.handle_callback_exception(self._handlers.get(fd)) except Exception: self.handle_callback_exception(self._handlers.get(fd)) + fd_obj = handler_func = None finally: # reset the stopped flag so another start/stop pair can be issued diff --git a/tornado/platform/twisted.py b/tornado/platform/twisted.py index 737032d57..5ef4e9b0f 100644 --- a/tornado/platform/twisted.py +++ b/tornado/platform/twisted.py @@ -378,15 +378,15 @@ class _FD(object): def doRead(self): if not self.lost: - self.handler(self.fd, tornado.ioloop.IOLoop.READ) + self.handler(self.fileobj, tornado.ioloop.IOLoop.READ) def doWrite(self): if not self.lost: - self.handler(self.fd, tornado.ioloop.IOLoop.WRITE) + self.handler(self.fileobj, tornado.ioloop.IOLoop.WRITE) def connectionLost(self, reason): if not self.lost: - self.handler(self.fd, tornado.ioloop.IOLoop.ERROR) + self.handler(self.fileobj, tornado.ioloop.IOLoop.ERROR) self.lost = True def logPrefix(self): diff --git a/tornado/test/ioloop_test.py b/tornado/test/ioloop_test.py index 382adb41c..3e888d3dd 100644 --- a/tornado/test/ioloop_test.py +++ b/tornado/test/ioloop_test.py @@ -199,6 +199,31 @@ class TestIOLoop(AsyncTestCase): io_loop.close(all_fds=True) self.assertTrue(socket_wrapper.closed) + def test_handler_callback_file_object(self): + """The handler callback receives the same fd object it passed in.""" + server_sock, port = bind_unused_port() + fds = [] + def handle_connection(fd, events): + fds.append(fd) + conn, addr = server_sock.accept() + conn.close() + self.stop() + self.io_loop.add_handler(server_sock, handle_connection, IOLoop.READ) + with contextlib.closing(socket.socket()) as client_sock: + client_sock.connect(('127.0.0.1', port)) + self.wait() + self.io_loop.remove_handler(server_sock) + self.io_loop.add_handler(server_sock.fileno(), handle_connection, + IOLoop.READ) + with contextlib.closing(socket.socket()) as client_sock: + client_sock.connect(('127.0.0.1', port)) + self.wait() + self.assertIs(fds[0], server_sock) + self.assertIs(fds[1], server_sock.fileno()) + self.io_loop.remove_handler(server_sock.fileno()) + server_sock.close() + + # Deliberately not a subclass of AsyncTestCase so the IOLoop isn't # automatically set as current.