diff -r a5bd41cae6df Lib/test/test_epoll.py --- a/Lib/test/test_epoll.py Thu Jan 16 18:58:01 2014 +0100 +++ b/Lib/test/test_epoll.py Mon Jan 20 11:23:36 2014 +0100 @@ -255,6 +255,17 @@ class TestEPoll(unittest.TestCase): self.addCleanup(epoll.close) self.assertEqual(os.get_inheritable(epoll.fileno()), False) + def test_timeout_rounding(self): + # epoll_wait() has a resolution of 1 millisecond, check if the timeout + # is correctly rounded to the upper bound + epoll = select.epoll() + self.addCleanup(epoll.close) + for timeout in (1e-2, 1e-3, 1e-4): + t0 = time.perf_counter() + epoll.poll(timeout) + dt = time.perf_counter() - t0 + self.assertGreaterEqual(dt, timeout) + def test_main(): support.run_unittest(TestEPoll) diff -r a5bd41cae6df Modules/selectmodule.c --- a/Modules/selectmodule.c Thu Jan 16 18:58:01 2014 +0100 +++ b/Modules/selectmodule.c Mon Jan 20 11:23:36 2014 +0100 @@ -1458,7 +1458,9 @@ pyepoll_poll(pyEpoll_Object *self, PyObj return NULL; } else { - timeout = (int)(dtimeout * 1000.0); + /* epoll_wait() has a resolution of 1 millisecond, round to the upper + bound to wait *at least* dtimeout seconds. */ + timeout = (int)ceil(dtimeout * 1000.0); } if (maxevents == -1) {