summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2017-10-13 20:49:43 (GMT)
committerGitHub <noreply@github.com>2017-10-13 20:49:43 (GMT)
commitef611c96eab0ab667ebb43fdf429b319f6d99890 (patch)
tree39623a7ea31b55dc13dfc2a5d3955ff7ae77e537 /Modules
parenta505ecdc5013cd8f930aacc1ec4fb2afa62d3853 (diff)
downloadcpython-ef611c96eab0ab667ebb43fdf429b319f6d99890.zip
cpython-ef611c96eab0ab667ebb43fdf429b319f6d99890.tar.gz
cpython-ef611c96eab0ab667ebb43fdf429b319f6d99890.tar.bz2
bpo-30807: signal.setitimer() now uses _PyTime API (GH-3865)
The _PyTime API handles detects overflow and is well tested. Document that the signal will only be sent once if internal is equal to zero.
Diffstat (limited to 'Modules')
-rw-r--r--Modules/clinic/signalmodule.c.h12
-rw-r--r--Modules/signalmodule.c40
2 files changed, 31 insertions, 21 deletions
diff --git a/Modules/clinic/signalmodule.c.h b/Modules/clinic/signalmodule.c.h
index a4542cc..cc3e640 100644
--- a/Modules/clinic/signalmodule.c.h
+++ b/Modules/clinic/signalmodule.c.h
@@ -182,18 +182,18 @@ PyDoc_STRVAR(signal_setitimer__doc__,
{"setitimer", (PyCFunction)signal_setitimer, METH_FASTCALL, signal_setitimer__doc__},
static PyObject *
-signal_setitimer_impl(PyObject *module, int which, double seconds,
- double interval);
+signal_setitimer_impl(PyObject *module, int which, PyObject *seconds,
+ PyObject *interval);
static PyObject *
signal_setitimer(PyObject *module, PyObject **args, Py_ssize_t nargs)
{
PyObject *return_value = NULL;
int which;
- double seconds;
- double interval = 0.0;
+ PyObject *seconds;
+ PyObject *interval = NULL;
- if (!_PyArg_ParseStack(args, nargs, "id|d:setitimer",
+ if (!_PyArg_ParseStack(args, nargs, "iO|O:setitimer",
&which, &seconds, &interval)) {
goto exit;
}
@@ -440,4 +440,4 @@ exit:
#ifndef SIGNAL_PTHREAD_KILL_METHODDEF
#define SIGNAL_PTHREAD_KILL_METHODDEF
#endif /* !defined(SIGNAL_PTHREAD_KILL_METHODDEF) */
-/*[clinic end generated code: output=3f6e6298696f1b75 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=a003d3fea9a33daa input=a9049054013a1b77]*/
diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c
index 6633108..d470727 100644
--- a/Modules/signalmodule.c
+++ b/Modules/signalmodule.c
@@ -131,16 +131,21 @@ static HANDLE sigint_event = NULL;
#ifdef HAVE_GETITIMER
static PyObject *ItimerError;
-/* auxiliary functions for setitimer/getitimer */
-static void
-timeval_from_double(double d, struct timeval *tv)
+/* auxiliary functions for setitimer */
+static int
+timeval_from_double(PyObject *obj, 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;
+ if (obj == NULL) {
+ tv->tv_sec = 0;
+ tv->tv_usec = 0;
+ return 0;
+ }
+
+ _PyTime_t t;
+ if (_PyTime_FromSecondsObject(&t, obj, _PyTime_ROUND_CEILING) < 0) {
+ return -1;
}
+ return _PyTime_AsTimeval(t, tv, _PyTime_ROUND_CEILING);
}
Py_LOCAL_INLINE(double)
@@ -677,8 +682,8 @@ PySignal_SetWakeupFd(int fd)
signal.setitimer
which: int
- seconds: double
- interval: double = 0.0
+ seconds: object
+ interval: object(c_default="NULL") = 0.0
/
Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL or ITIMER_PROF).
@@ -690,14 +695,19 @@ Returns old values as a tuple: (delay, interval).
[clinic start generated code]*/
static PyObject *
-signal_setitimer_impl(PyObject *module, int which, double seconds,
- double interval)
-/*[clinic end generated code: output=6f51da0fe0787f2c input=0d27d417cfcbd51a]*/
+signal_setitimer_impl(PyObject *module, int which, PyObject *seconds,
+ PyObject *interval)
+/*[clinic end generated code: output=65f9dcbddc35527b input=de43daf194e6f66f]*/
{
struct itimerval new, old;
- timeval_from_double(seconds, &new.it_value);
- timeval_from_double(interval, &new.it_interval);
+ if (timeval_from_double(seconds, &new.it_value) < 0) {
+ return NULL;
+ }
+ if (timeval_from_double(interval, &new.it_interval) < 0) {
+ return NULL;
+ }
+
/* Let OS check "which" value */
if (setitimer(which, &new, &old) != 0) {
PyErr_SetFromErrno(ItimerError);