# and the handler should have been called
self.assertEqual(self.hndl_called, True)
+ def test_setitimer_tiny(self):
+ # bpo-30807: C setitimer() takes a microsecond-resolution interval.
+ # Check that float -> timeval conversion doesn't round
+ # the interval down to zero, which would disable the timer.
+ self.itimer = signal.ITIMER_REAL
+ signal.setitimer(self.itimer, 1e-6)
+ time.sleep(1)
+ self.assertEqual(self.hndl_called, True)
+
class PendingSignalsTests(unittest.TestCase):
"""
--- /dev/null
+signal.setitimer() may disable the timer when passed a tiny value.
+
+Tiny values (such as 1e-6) are valid non-zero values for setitimer(), which
+is specified as taking microsecond-resolution intervals. However, on some
+platform, our conversion routine could convert 1e-6 into a zero interval,
+therefore disabling the timer instead of (re-)scheduling it.
{
tv->tv_sec = floor(d);
tv->tv_usec = fmod(d, 1.0) * 1000000.0;
+ /* Don't disable the timer if the computation above rounds down to zero. */
+ if (d > 0.0 && tv->tv_sec == 0 && tv->tv_usec == 0) {
+ tv->tv_usec = 1;
+ }
}
Py_LOCAL_INLINE(double)