[Python-Dev] Signals, threads, blocking C functions

Adam Olsen rhamph at gmail.com
Tue Sep 12 06:05:38 CEST 2006


On 9/11/06, Gustavo Carneiro <gjcarneiro at gmail.com> wrote:
> On 9/11/06, Adam Olsen <rhamph at gmail.com> wrote:
> > This much would allow a GUI's poll loop to wake up when there is a
> > signal, and give control back to the python main loop, which could
> > then read off the signals and queue up their handler functions.
>
>   I like this approach.  Not only we would get a poll-able file
> descriptor to notify a GUI main loop when signals arrive, we'd also
> avoid the lack of async safety in Py_AddPendingCall /
> Py_MakePendingCalls which affects _current_ Python code.
>
>   Note that the file descriptor of the read end of the pipe has to
> become a public Python API so that 3rd party extensions may poll it.
> This is crucial.

Yeah, so long as Python still does the actual reading.


> > The only problem is when there is no GUI poll loop.  We don't want
> > python to have to poll the fd, we'd rather it just check a variable.
> > Is it possible to set/clear a flag in a sufficiently portable
> > (reentrant-safe, non-blocking, thread-safe) fashion?
>
>   It's simple.  That pipe file descriptor has to be changed to
> non-blocking mode in both ends of the pipe, obviously, with fcntl.
> Then, to find out whether a signal happened or not we modify
> PyErr_CheckSignals() to try to read from the pipe.  If it reads bytes
> from the pipe, we process the corresponding python signal handlers or
> raise KeyboardInterrupt.  If the read() syscall returns zero bytes
> read, we know no signal was delivered and move on.

Aye, but my point was that a syscall is costly, and we'd like to avoid
it if possible.

We'll probably have to benchmark it though, to find out if it's worth
the hassle.


>   The only potential problem left is that, by changing the pipe file
> descriptor to non-blocking mode we can only write as many bytes to it
> without reading from the other side as the pipe buffer allows.  If a
> large number of signals arrive very quickly, that buffer may fill and
> we lose signals.  But I think the default buffer should be more than
> enough.  And normally programs don't receive lots of signals in a
> small time window.  If it happens we may lose signals, but that's very
> rare, and who cares anyway.

Indeed, we need to document very clearly that:
* Signals may be dropped if there is a burst
* Signals may be delayed for a very long time, and if you replace a
previous handler your new handler may get signals intended for the old
handler

-- 
Adam Olsen, aka Rhamphoryncus


More information about the Python-Dev mailing list