Subject: Re: port better to POSIX hosts lacking _setjmp

From: Paul Eggert <[email-masked]>
Date: Sat, 15 Sep 2012 00:50:17 -0700

On 09/15/2012 12:12 AM, Eli Zaretskii wrote:
> On which platforms does longjmp change the signal
> mask and how, and in what ways can this "mess things up and slow
> things down"?

For example, under FreeBSD, setjmp saves the signal mask,
and longjmp restores the signal mask to the value that it had
when setjmp was called.  See
<http://www.freebsd.org/cgi/man.cgi?query=setjmp&manpath=FreeBSD+9.0-RELEASE>.
FreeBSD is not alone in this -- it's sort of a BSD tradition --
but I don't have a list handy of exactly which OSes do it and
which do not.

Saving and restoring the signal mask takes time -- often system
calls are involved.  Emacs doesn't need the mask saved and restored,
typically, so the effort is wasted.  It's not uncommon for
_setjmp+_longjmp to be 30x faster than setjmp+longjmp.  This is
partly why Emacs has long preferred _setjmp if available.

Messups are trickier, because they involve rare race conditions.
They can occur if Emacs or a system call has set the signal mask to X,
but a longjump unexpectedly changes it to Y, where Y is not equal to X.
This can happen if a signal handler invokes longjmp, either directly
or indirectly.  For example, Emacs signal handlers can invoke xmalloc,
which can do a longjmp if memory is full, leading to a rare bug.

Arguably signal handlers should not invoke malloc -- and I'll
submit a patch shortly along those lines -- but regardless,
it's better if Emacs's nonlocal gotos uniformly leave
the signal mask alone, rather than leaving it alone on some hosts
and messing with it on others.