[Python-Dev] Re: Signal-resistant code

Guido van Rossum guido@python.org
Thu, 05 Sep 2002 16:46:27 -0400


> > I admit that I hate signals so badly that whenever I needed to wait
> > for a child to finish I would always structure the program around this
> > need (even when coding in C).
> 
> Ummm... if you really hate signals that much perhaps you to step aside 
> from this particular discussion? Naturally, you will get to pronounce on 
> the results that come out of it (if any ;-)

Why?  I don't think hating signals disqualifies me from understanding
their problems.

> So what are the three problems of signals?  
> 
> One - what calls are allowed by the platform inside a signal handler.
> No problem.  Nobody suggested actually executing Python code inside a
> signal handler so we don't need to be worried about user code. The C
> handler doesn't call anything unusual, just sets flags.  This should work 
> on all platforms.
> 
> Two - Interruptible system calls.  If all Python I/O calls are wrapped
> inside restarting wrappers this should be solved.

I asked what the Python code called by the wrapper when a signal
arrives is allowed to do (e.g. close the file?).  If you replied to
that, I missed it.

> If the system's libc wraps them it can be disabled by SA_RESTART
> (posix) or siginterrupt (BSD).  On some systems read and recv return
> a short buffer instead of EINTR.

This latter sentence shows that you don't understand signals, or
you're being very sloppy.  You get *either* a short buffer *or* EINTR
depending on whether some data was already transferred to user space.

> This can be safely ignored because it only happens for pipes and
> sockets where this is a valid result. AFAIR it's guaranteed not to
> happen on regular files so we won't be tricked into believing they
> reached EOF.

I don't believe that a short read on a regular file can be used
reliably to infer EOF anyway.  The file could be growing while we
read.

> Are there any systems where system calls are interruptible but not
> restartable in any way without data loss?

Not AFAIK.

> Three - Threads playing "who gets the signal".  The Python signal module
> has a hack that appears to work on all relevant platform - ignore the
> signal if getpid() isn't the main thread.

Doesn't that make signals unreliable?  What if thread 4 has forked a
child, and the child exist?  Won't the SIGCHLD be sent to thread 4?
AFAIK there's no standard for this, or if there is, not all systems
comply.

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