[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: cannot kill slapd from openldap-1.2.11

Villy Kruse wrote:
> On Tue, 18 Jul 2000, Terry Lambert wrote:
> > The problem is system call restart on the select, following
> > the select being interrupted by a caught signal.
> Just a question:  Should catching a signal cause select
> to return error EINTR according to BSD standard?

On a true BSD system, no.  The system call will be

BSD 4.3 added the capability to change the restart
behaviour for all signals for the entire process.  This
came from DEC Ultrix 4.1 which was based on BSD 4.2,
and the call was named "siginterrupt(2)".  Modern BSD
systems have a comapatability function for this in the
C library, "siginterupt(3)".

The canonically correct way to interrupt a system call
from a signal handler called with the system call in
progress, on a BSD system at least, is to setjmp()
before making the call, and to longjmp() out of the
signal handler.

> On linux with glibc2 which tries to follow BSD standard
> with respect to the signal() semantics, the read() and
> write() will be automatically restarted, whereas select()
> will return with error EINTR after a signal handler has
> returned.

Well, the behaviour in the more recent BSDs, who have bent
over for POSIX on signals and things like deleting all
locks on a file held by a process when _any_ fd in the
process referencing the file is closed (makes it real hard
to implement an NFS lockd/statd), is to do what POSIX says
to do.

The FreeBSD threads implementation, though, uses a call
conversion scheduler, which trades a blocking call for a
non-blocking call plus a context switch.  Since many calls
do not have non-blocking versions, or do not respect the
O_NDELAY flag on the fd they are called upon (e.g. select),
there has to be a scheduler entry.

Linux doesn't have this, so its library emulation is going
to be a bit off, unless one is very, very careful about

> On linux with the older libc5 the signal() follows sysv
> semantics, and as a result of that a few programs which
> relied in sysv signals no longer reacted on signals.

Yes.  This is a bad thing for an OS to change, particularly
in these days of "autoconfig" making all sorts of embedded
assumptions about various platforms.

> If it isn't then you could get strange, hard to debug,
> errors which seams to happen at random.  Also bear in mind
> that if system calls are not automaticaly restarted then the
> program should do that anytime a system call returns EINTR
> and the situation does not call for an abort at this point.
> If the signal handler longjmps (must be siglongjmp where
> available) back to the main loop then you need not worry
> about restarting anything.

Right.  The issue is that sa_flags in the sigaction struct
may or may not support SA_RESTART.

The thing to do is to use the POSIX interfaces, not the
legacy interfaces, and then to #if test for SA_RESTART
having been defined.

> In short, does the POSIX draft now specify the semantics
> for signals(), and is that going to be sysv or BSD or
> something in between?  And X-OPEN?

It is platform defined whether signals are sent to any
available thread, or to a signla handling thread (there
was a long-standing bug in MySQL, also having to do with
shutdown, which made some bad assumptions about the
pthread_signal call.

You could argue that perhaps the best way to handle any
signals in a treaded environment, and do it without a
platform assumption or dependency, would be to catch the
signals in a signal handler set up before the first
pthread_create (i.e. in "main"), and then to rethrow them
to a specific handler thread using "pthread_signal".  But
the MySQL bug was actually a bug in the pthread_signal()
call on some platforms (notably AIX).

So the easiest way is stil to longjmp.

The sigsetjmp/siglongjmp routines were invented to deal
with people doing things that POSIX expressly forbids
while you are in a signal handler, like using floating

> The following litle program can be used to test the signal
> behaviour with respect to read() and select() restarts.

[ ... ]

It might be a good idea to integrate this into the
autoconfig environment detection.  But I think it will
still fall short, unless you do the work in a couple
of threads, to gauge thread interactions as well (see
above).  This whole thing was made a lot more painful
than it had to be by POSIX being unwilling to render
any exisitng implementations defacto non-conformant,
unfortunately.  The decision appears (to me) to have
been politically rather than technically motivated.

-- Terry Lambert
-- Whistle Communications, Inc., an I.B.M. Company
-- terry@whistle.com
This is formal notice under California Assembly Bill 1629, enacted
9/26/98 that any UCE sent to my email address will be billed $50
per incident to the legally allowed maximum of $25,000.