summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell Davis <551404+russelldavis@users.noreply.github.com>2020-04-15 18:57:06 (GMT)
committerGitHub <noreply@github.com>2020-04-15 18:57:06 (GMT)
commitba1bcffe5cafc1bb0ac6fdf9ecef51e75e342707 (patch)
tree59682606714c5402a5bb72f8926a4d5f7b69323d
parent4b4e90a51848578dc06341777a929a0be4f4757f (diff)
downloadcpython-ba1bcffe5cafc1bb0ac6fdf9ecef51e75e342707.zip
cpython-ba1bcffe5cafc1bb0ac6fdf9ecef51e75e342707.tar.gz
cpython-ba1bcffe5cafc1bb0ac6fdf9ecef51e75e342707.tar.bz2
bpo-29255: Wait in KqueueSelector.select when no fds are registered (GH-19508)
Also partially fixes bpo-25680 (there's still a discrepancy in behavior on Windows that needs to be fixed).
-rw-r--r--Lib/selectors.py5
-rw-r--r--Lib/test/test_selectors.py13
-rw-r--r--Misc/NEWS.d/next/Library/2020-04-14-11-31-07.bpo-29255.4EcyIN.rst1
3 files changed, 18 insertions, 1 deletions
diff --git a/Lib/selectors.py b/Lib/selectors.py
index a9a0801..90251dc 100644
--- a/Lib/selectors.py
+++ b/Lib/selectors.py
@@ -552,7 +552,10 @@ if hasattr(select, 'kqueue'):
def select(self, timeout=None):
timeout = None if timeout is None else max(timeout, 0)
- max_ev = len(self._fd_to_key)
+ # If max_ev is 0, kqueue will ignore the timeout. For consistent
+ # behavior with the other selector classes, we prevent that here
+ # (using max). See https://bugs.python.org/issue29255
+ max_ev = max(len(self._fd_to_key), 1)
ready = []
try:
kev_list = self._selector.control(None, max_ev, timeout)
diff --git a/Lib/test/test_selectors.py b/Lib/test/test_selectors.py
index 3161122..c449155 100644
--- a/Lib/test/test_selectors.py
+++ b/Lib/test/test_selectors.py
@@ -543,6 +543,19 @@ class KqueueSelectorTestCase(BaseSelectorTestCase, ScalableSelectorMixIn):
with self.assertRaises(KeyError):
s.get_key(bad_f)
+ def test_empty_select_timeout(self):
+ # Issues #23009, #29255: Make sure timeout is applied when no fds
+ # are registered.
+ s = self.SELECTOR()
+ self.addCleanup(s.close)
+
+ t0 = time()
+ self.assertEqual(s.select(1), [])
+ t1 = time()
+ dt = t1 - t0
+ # Tolerate 2.0 seconds for very slow buildbots
+ self.assertTrue(0.8 <= dt <= 2.0, dt)
+
@unittest.skipUnless(hasattr(selectors, 'DevpollSelector'),
"Test needs selectors.DevpollSelector")
diff --git a/Misc/NEWS.d/next/Library/2020-04-14-11-31-07.bpo-29255.4EcyIN.rst b/Misc/NEWS.d/next/Library/2020-04-14-11-31-07.bpo-29255.4EcyIN.rst
new file mode 100644
index 0000000..18fbddf
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-04-14-11-31-07.bpo-29255.4EcyIN.rst
@@ -0,0 +1 @@
+Wait in `KqueueSelector.select` when no fds are registered