[Python-Dev] Re: Signal-resistant code
Fri, 6 Sep 2002 01:23:30 +0300
On Thu, Sep 05, 2002 at 04:46:27PM -0400, Guido van Rossum wrote:
> > > 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.
In the past I have disqualified myself from making technical decisions on
issues where I have been burned and knew that my opinion would be a calm
> 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.
Anything that a Python thread is allowed to do without grabbing a
lock, i.e. anything that involves only exclusive resources or atomic
Python operations on shared resources like setting a variable (but
not read-modify-write). A signal handler is also allowed to raise an
exception that will get delivered to the main thread.
> > 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.
Did I say that you get *both* a short buffer *and* EINTR? What I meant
is that it's really quite simple - if errno==EINTR I retry and if I get
a short buffer I continue from whatever I got and ask for the remainder
and this should work regardless of the differences in behavior between
different systems, sockets and files, etc.
> > 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.
You're right, only a zero result on read should be interpreted as EOF,
not a short result. I got confused by fread where a short read does mark
an end of file condition. I don't see how the growing file case is
> > 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
I've never actually tried this one. I just went by the comments in
signalmodule.c which claim that this works for all cases of how different
implementations deliver signals to threads. I guess that was a bit hasty.