[Openmcl-devel] Handling Unix signals?

Gary Byers gb at clozure.com
Tue Dec 20 06:16:41 PST 2005

On Tue, 20 Dec 2005, Wojciech Kaczmarek wrote:

> Hello,
> is there a way to handle an Unix signal wrapped as a Lisp condition in
> Openmcl?
> The most simple example I have in mind is that a running image catches
> SIGTERM and just invokes save-application.
> Well I'm rather not experienced lisper and greping through the Openmcl
> sources nor searching this list' archives didn't revealed for me any
> clues how to do this.

It's probably a little harder to do this than it might seem to be
at first glance; when a thread receives a signal while running
lisp code, it needs to make sure that the signal context (which
contains the values of all registers at the point where the signal
occurred) gets saved where the GC can find it.  This has to happen
atomically; the way that it's usually done in the signal handlers
that're defined in C in the lisp kernel is (generally):

  a) specify that all signals are masked in the sigaction() call that
     installs the handler.
  b) when the handler's invoked, it
     i) obtains the current thread's "thread contest record" (TCR).
        This is a thread-local variable; some handlers may assume
        that it's available in a general-purpose register in the
        signal context.
     ii) create an "xframe_list* structure on the signal handler's
        stack.  Set the "curr" field of this structure to the
        signal context that the handler receives as an argument
        (via SA_SIGINFO).  Set the "prev" field in the structure
        to the value of the tcr's xframe slot, then set the tcr's
        xframe slot to point to the new (stack-allocated) xframe_list.
        (This basically pushes the new signal context on a thread-
        specific list of signal contexts and constitutes "putting
        the signal context where the GC can find it.")
     iii) mark the current thread as running foreign code;
     iv) unmask signals.

(I'm not sure that any of the kernel signal handlers ever do things
in quite as straightforward a manner as is suggested above; many of
them deal with signals related to exceptions and combine the steps
above with waiting for a lock that serializes exception handling and
letting the GC know that they're waiting.)

Anyway, there's at least a little bit of GC-related bookkeeping
that needs to happen when a signal handler interrupts lisp code,
and it's not clear that this could be safely done just by using
DEFCALLBACK to define a handler and using #_sigaction to install
it (though that might appear to work, some of the time.)  The
solution that -sounds- right (but isn't implemented) is to have
a little stub C function in the kernel that does the right
atomic-with-respect-to-the-GC things and calls out to lisp
code; that lisp code could then do fairly arbitrary things.

> -- 
> I couldn't trust the thinking of a man who takes
> the universe - if there's one - for granted
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/mailman/listinfo/openmcl-devel

More information about the Openmcl-devel mailing list