On Thu, Feb 1, 2018 at 4:57 AM, Victor Porton <por...@narod.ru> wrote: > Lawrence D’Oliveiro wrote: > >> On Thursday, February 1, 2018 at 8:10:24 AM UTC+13, Victor Porton wrote: >>> Lawrence D’Oliveiro wrote: >>> >>>> The usual behaviour for POSIX is that the call is aborted with EINTR >>>> after you get the signal. >>> >>> That poll() is interrupted does not imply that Python will run its >>> pythonic signal handler at the point of interruption. That is a problem. >> >> * Python calls poll() >> * poll() aborted with EINTR >> * Python runs your signal handler >> >> Versus native C code: >> >> * your code calls poll() >> * poll() aborted with EINTR >> * your signal handler is run >> >> Where is there a fundamental difference? > > I meant to call poll() from C code, not Python code. In this case when > poll() is aborted with EINTR, the pythonic signal handler does not run.
An extension module should call PyErr_CheckSignals [1] when interrupted by EINTR. For example, here's the loop used to call poll() in the standard-library select module: async_err = 0; do { Py_BEGIN_ALLOW_THREADS errno = 0; poll_result = poll(self->ufds, self->ufd_len, (int)ms); Py_END_ALLOW_THREADS if (errno != EINTR) break; /* poll() was interrupted by a signal */ if (PyErr_CheckSignals()) { async_err = 1; break; } if (timeout >= 0) { timeout = deadline - _PyTime_GetMonotonicClock(); if (timeout < 0) { poll_result = 0; break; } ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING); /* retry poll() with the recomputed timeout */ } } while (1); self->poll_running = 0; if (poll_result < 0) { if (!async_err) PyErr_SetFromErrno(PyExc_OSError); return NULL; } [1]: https://docs.python.org/3/c-api/exceptions.html#c.PyErr_CheckSignals -- https://mail.python.org/mailman/listinfo/python-list