[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: System calls interrupted by signals - or not
From: |
Danny Milosavljevic |
Subject: |
Re: System calls interrupted by signals - or not |
Date: |
Thu, 1 Feb 2018 10:33:34 +0100 |
Hi Mark,
On Thu, 01 Feb 2018 03:13:33 -0500
Mark H Weaver <address@hidden> wrote:
> Guile is a library meant for use within existing applications, and
> therefore needs to be able to cope with whatever signal handling policy
> those applications have chosen. We certainly cannot assume that all
> kinds of signals will be configured for SA_RESTART.
That's too bad. It can't be helped, then.
Then see the table for a little overview.
(I've tried very hard to sensibly handle EINTR in the past and it's
surprisingly difficult - that table is what I got out of it - and
the decision to avoid PC-losering signals whenever I can)
And even for the purported use of EINTR (so that you can have complicated
signal-unsafe handler actions after an "if (errno == EINTR)" block)
it's difficult to get right. That's because you only get EINTR when a system
call has been interrupted by a signal. It can happen that you aren't yet in
the system call, the signal handler runs (to completion), and then you enter a
system call.
You *don't* get EINTR for the missed signal then.
I don't know what they were thinking.
> There are cases where you may want the
> ability to interrupt a system call without killing the thread. Suppose
> you are waiting for a large I/O operation to complete over a slow
> network or device. Signals are the only way I know of in POSIX to
> interrupt a system call, but it can only be done if there's at least one
> kind of signal that's not configured for SA_RESTART.
That's a good point.
But many people just use
do { syscall } while (errno == EINTR);
in random libraries and then you can't interrupt the system call after all
in your user program.
Also, there's a race because you can be right before entering a system call,
your signal handler runs, and then the system call isn't interrupted after
all (because there was nothing to interrupt - and now you can't branch
on it anymore. That's how I started to enter this EINTR rabbit hole -
one of my programs had such a bug).
> "When you don’t specify with ‘sigaction’ or ‘siginterrupt’ what a
> particular handler should do, it uses a default choice. The default
> choice in the GNU C Library is to make primitives fail with ‘EINTR’."
:-(