[Python-Dev] Signals+Threads (PyGTK waking up 10x/sec).

Guido van Rossum guido at python.org
Sat Dec 8 11:01:58 CET 2007


Adam, perhaps at some point (Monday?) we could get together on
#python-dev and interact in real time on this issue. Probably even
better on the phone. This offer is open to anyone who is serious about
getting this resolved. Someone please take it -- I'm offering free
consulting here!

I'm curious -- is there anyone here who understands why [Py]GTK is
using signals anyway? It's not like writing robust signal handling
code in C is at all easy or obvious. If instead of a signal a file
descriptor could be used, all problems would likely be gone.

--Guido

On Dec 7, 2007 3:27 PM, Adam Olsen <rhamph at gmail.com> wrote:
> On Dec 7, 2007 2:35 PM,  <glyph at divmod.com> wrote:
> >
> > On 02:48 pm, gjcarneiro at gmail.com wrote:
> > >Not only that, but current python signal handling is not theorethically
> > >async safe; there are race conditions in the Py_AddPendingCalls API,
> > >and it
> > >just happens to work most of the time.
>
> [This refers to the internal datastructures used by
> Py_AddPendingCalls, which aren't updated in a safe way.
> Hard/impossible to fix in C, but fairly easy with embedded assembly.]
>
>
> > Twisted has encountered one such issue, described here:
> >
> >     http://twistedmatrix.com/trac/ticket/1997#comment:12
>
> [This refers to the overall design, which is inherently racey.]
>
>
> > Unfortunately, I don't know enough about signals to suggest or comment
> > on the solution.  Any Python/C wrapper around a syscall which can be
> > interrupted needs to somehow atomically check for the presence of
> > pending python signal handlers; I don't know of any POSIX API to do
> > that.
>
> Overall, what you'd need to do is register a wakeup function (to be
> called by a signal handler or another thread), and have that wakeup
> function cancel whatever you're doing.  The hard part is it needs to
> work at *ANY* time while it's registered, before you've even called
> the library function or syscall you intend to cancel!
>
> I currently know of two methods of achieving this:
> 1) If reading a file or socket, first poll the fd, then do a
> non-blocking read.  The wakeup function writes to a wakeup pipe you
> also poll, which then wakes you up.  A wakeup after poll completes is
> ignored, but the non-blocking read will finish promptly enough anyway.
> 2) Use sigsetjmp before a syscall (I wouldn't trust a library call),
> then have the signal handler jump completely out of the operation.
> This is evil and unportable, but probably works.
>
> Additionally, this only gets SIGINT with the default behaviour to work
> right, as it can be entirely implemented in C.  If you want to handle
> arbitrary signals running arbitrary python code you really need a
> second thread to run them in.
>
> --
> Adam Olsen, aka Rhamphoryncus
>
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> http://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe: http://mail.python.org/mailman/options/python-dev/guido%40python.org
>



-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)


More information about the Python-Dev mailing list