From: Ben Darnell Date: Fri, 29 Jun 2012 07:53:22 +0000 (-0700) Subject: Disallow multiple calls to add_handler for the same fd in IOLoop. X-Git-Tag: v2.4.0~44 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ed7030d280962a2ba5a9861689eecd6edbabfd94;p=thirdparty%2Ftornado.git Disallow multiple calls to add_handler for the same fd in IOLoop. This was already true for epoll; this change adds a check for kqueue and select implementations. --- diff --git a/tornado/ioloop.py b/tornado/ioloop.py index 3e1422989..70eb5564b 100644 --- a/tornado/ioloop.py +++ b/tornado/ioloop.py @@ -553,6 +553,8 @@ class _KQueue(object): self._kqueue.close() def register(self, fd, events): + if fd in self._active: + raise IOError("fd %d already registered" % fd) self._control(fd, events, select.KQ_EV_ADD) self._active[fd] = events @@ -614,6 +616,8 @@ class _Select(object): pass def register(self, fd, events): + if fd in self.read_fds or fd in self.write_fds or fd in self.error_fds: + raise IOError("fd %d already registered" % fd) if events & IOLoop.READ: self.read_fds.add(fd) if events & IOLoop.WRITE: diff --git a/tornado/test/ioloop_test.py b/tornado/test/ioloop_test.py index df2cd7771..2ebdbcea8 100644 --- a/tornado/test/ioloop_test.py +++ b/tornado/test/ioloop_test.py @@ -3,10 +3,13 @@ from __future__ import absolute_import, division, with_statement import datetime -import unittest +import socket import time +import unittest -from tornado.testing import AsyncTestCase, LogTrapTestCase +from tornado.ioloop import IOLoop +from tornado.netutil import bind_sockets +from tornado.testing import AsyncTestCase, LogTrapTestCase, get_unused_port class TestIOLoop(AsyncTestCase, LogTrapTestCase): @@ -31,5 +34,20 @@ class TestIOLoop(AsyncTestCase, LogTrapTestCase): self.io_loop.add_timeout(datetime.timedelta(microseconds=1), self.stop) self.wait() + def test_multiple_add(self): + [sock] = bind_sockets(get_unused_port(), '127.0.0.1', + family=socket.AF_INET) + try: + self.io_loop.add_handler(sock.fileno(), lambda fd, events: None, + IOLoop.READ) + # Attempting to add the same handler twice fails + # (with a platform-dependent exception) + self.assertRaises(Exception, self.io_loop.add_handler, + sock.fileno(), lambda fd, events: None, + IOLoop.READ) + finally: + sock.close() + + if __name__ == "__main__": unittest.main()