Skip to content

Commit

Permalink
Disallow multiple calls to add_handler for the same fd in IOLoop.
Browse files Browse the repository at this point in the history
This was already true for epoll; this change adds a check for
kqueue and select implementations.
  • Loading branch information
bdarnell committed Jun 29, 2012
1 parent cfd7a96 commit ed7030d
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 2 deletions.
4 changes: 4 additions & 0 deletions tornado/ioloop.py
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,8 @@ def close(self):
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

Expand Down Expand Up @@ -614,6 +616,8 @@ def close(self):
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:
Expand Down
22 changes: 20 additions & 2 deletions tornado/test/ioloop_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -31,5 +34,20 @@ def test_add_timeout_timedelta(self):
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()

0 comments on commit ed7030d

Please sign in to comment.