Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions Doc/library/signal.rst
Original file line number Diff line number Diff line change
Expand Up @@ -273,13 +273,14 @@ The :mod:`signal` module defines the following functions:
.. versionadded:: 3.3


.. function:: setitimer(which, seconds[, interval])
.. function:: setitimer(which, seconds, interval=0.0)

Sets given interval timer (one of :const:`signal.ITIMER_REAL`,
:const:`signal.ITIMER_VIRTUAL` or :const:`signal.ITIMER_PROF`) specified
by *which* to fire after *seconds* (float is accepted, different from
:func:`alarm`) and after that every *interval* seconds. The interval
timer specified by *which* can be cleared by setting seconds to zero.
:func:`alarm`) and after that every *interval* seconds (if *interval*
is non-zero). The interval timer specified by *which* can be cleared by
setting *seconds* to zero.

When an interval timer fires, a signal is sent to the process.
The signal sent is dependent on the timer being used;
Expand Down
12 changes: 6 additions & 6 deletions Modules/clinic/signalmodule.c.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -440,4 +440,4 @@ signal_pthread_kill(PyObject *module, PyObject **args, Py_ssize_t nargs)
#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]*/
40 changes: 25 additions & 15 deletions Modules/signalmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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).
Expand All @@ -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);
Expand Down