mirror of https://github.com/python/cpython
bpo-30807: signal.setitimer() may disable the timer by mistake (#2493)
* bpo-30807: signal.setitimer() may disable the timer by mistake * Add NEWS blurb
This commit is contained in:
parent
42bc8beadd
commit
729780a810
|
@ -608,6 +608,15 @@ class ItimerTest(unittest.TestCase):
|
|||
# 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):
|
||||
"""
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
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.
|
|
@ -139,6 +139,10 @@ timeval_from_double(double d, struct timeval *tv)
|
|||
{
|
||||
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)
|
||||
|
|
Loading…
Reference in New Issue