On Wed, 1 Nov 2017 20:29:56 +0200
Koos Zevenhoven <k7hoven@gmail.com> wrote:
>
> From a correctness point of view, that is absolutely great: if
> PyErr_CheckSignals() is called, it is guaranteed to notice a new signal
> regardles of how small the number of picoseconds after the `is_tripped`
> flag has been set. But is that really important?
I was going to answer "no"... but actually yes. The important case is
the event loop type case:
while (1) {
select([some file descriptors]);
if (errno == EINTR) {
PyErr_CheckSignals();
if (PyErr_Occurred()) break;
}
/* continue select()ing... */
}
Now say at a given point in time, no fds are actually active (or even
waited for), but some signal arrives (SIGINT perhaps).
select() is woken up and returns with errno EINTR. Two things then can
happen:
- if PyErr_CheckSignals() notices the signal, it will run the relevant
signal handler, which may raise an exception and trigger the select()
loop to exit (e.g. SIGINT would raise KeyboardInterrupt)
- if PyErr_CheckSignals() misses the signal, the loop will enter again,
and select() may sleep for an infinite amount of time
Oh! So that would provide a proper reason for my just-in-case decision to name the faster near-equivalent functionality PyErr_PROBE_SIGNALS instead of PyErr_CHECK_SIGNALS.Cross-referencing to that (thread about making Ctrl-C "always" work):Of course, what we're doing with select() above can already apply for
read() or other interruptible syscalls waiting for outside data... and
that pattern is present a lot internally, especially since
PEP 475 ("Retry system calls failing with EINTR").
Now, is the "sequentially consistent" ordering on is_tripped sufficient
to guarantee that signals won't be missed on a weak-ordering platform?
I *think* so, but an expert would need to check that code (or we
cross our fingers and wait for a hypothetical bug report).
I think the question is: Do we know for sure that is_tripped has been stored using sequentially consistent ordering prior to the call to PyErr_CheckSignals(), even if an interruptible syscall is involved? I suppose so?(But this is a separate question from the problem I was solving, of course. I'm not proposing to remove PyErr_CheckSignals())