From ba6960d1414be5d100223ece7e5b56b6aaaea548 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 23 Jan 2011 17:31:43 -0800 Subject: [PATCH] Fixes #74, removing filenos from the hub when they raise a value error, thanks to Edward George for the repro and fix. --- AUTHORS | 1 + eventlet/hubs/poll.py | 33 +++++++++++++++++++-------------- tests/hub_test.py | 9 +++++++++ 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/AUTHORS b/AUTHORS index b82c438..92e0a1d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -67,3 +67,4 @@ Thanks To * Malcolm Cleaton, patch for Event exception handling * Alexey Borzenkov, for finding and fixing issues with Windows error detection (#66, #69), reducing dependencies in zeromq hub (#71) * Anonymous, finding and fixing error in websocket chat example (#70) +* Edward George, finding and fixing an issue in the [e]poll hubs (#74) diff --git a/eventlet/hubs/poll.py b/eventlet/hubs/poll.py index 57ca580..096f1d0 100644 --- a/eventlet/hubs/poll.py +++ b/eventlet/hubs/poll.py @@ -38,21 +38,26 @@ class Hub(BaseHub): mask |= READ_MASK | EXC_MASK if self.listeners[WRITE].get(fileno): mask |= WRITE_MASK | EXC_MASK - if mask: - if new: - self.poll.register(fileno, mask) - else: - try: - self.modify(fileno, mask) - except (IOError, OSError): + try: + if mask: + if new: self.poll.register(fileno, mask) - else: - try: - self.poll.unregister(fileno) - except (KeyError, IOError, OSError): - # raised if we try to remove a fileno that was - # already removed/invalid - pass + else: + try: + self.modify(fileno, mask) + except (IOError, OSError): + self.poll.register(fileno, mask) + else: + try: + self.poll.unregister(fileno) + except (KeyError, IOError, OSError): + # raised if we try to remove a fileno that was + # already removed/invalid + pass + except ValueError: + # fileno is bad, issue 74 + self.remove_descriptor(fileno) + raise def remove_descriptor(self, fileno): super(Hub, self).remove_descriptor(fileno) diff --git a/tests/hub_test.py b/tests/hub_test.py index 002a93b..77df31f 100644 --- a/tests/hub_test.py +++ b/tests/hub_test.py @@ -168,6 +168,7 @@ class TestHubBlockingDetector(LimitedTestCase): gt = eventlet.spawn(look_im_blocking) self.assertRaises(RuntimeError, gt.wait) debug.hub_blocking_detection(False) + class TestSuspend(LimitedTestCase): TEST_TIMEOUT=3 @@ -205,6 +206,14 @@ except eventlet.Timeout: shutil.rmtree(self.tempdir) +class TestBadFilenos(LimitedTestCase): + @skip_with_pyevent + def test_repeated_selects(self): + from eventlet.green import select + self.assertRaises(ValueError, select.select, [-1], [], []) + self.assertRaises(ValueError, select.select, [-1], [], []) + + class Foo(object): pass