signals in MLton

Stephen Weeks sweeks@wasabi.epr.com
Mon, 9 Aug 1999 06:27:16 -0700 (PDT)


Well, after a long night of hacking, MLton has signal handling.  I've
included the current signature at the end of this message.  I think
I'll probably change it to get rid of sigset and to simply use lists
of signals.

Of course, all of the messiness is in the implementation.  Here is
is the basic idea.

There is a single signal handler hardwired into the C code.  This
signal handler sets the gc limit so that the next limit check will
fail.  This signal handler is only invoked for signals that ML wants
to handle.  The gc code checks to see whether it was invoked to
process a signal, and if so, calls the ML signal handler.  The ML
signal handler dispatches on the signal and calls the user signal
handler for that signal.  The signal handler runs on the same stack
and uses the same heap as the normal ML program.  GC's can happen
during signal handling, but callcc cannot be used and all further
signals are blocked until the signal handler terminates.  That is,
only one signal can be handled at a time.  Also, signals are blocked
during all of every GC as well as during other runtime systemy
operations like serialization.

As to the compiler innards, there were a couple of changes.  The Cps
language was changed ever so slightly.  A Cps program now has another
entry point in addition to main, namely, the signal handler.  The
closure converter was changed to create the magic signal handling
function, which uses a global ref cell to store the environment for
the actual signal handling function.  Fortunately, the flow analysis
didn't have to be changed, since it doesn't do any cutoffs based on
reachability and is flow-insensitive (meaning it doesn't take into
account statement order).  There was a little bit of change to the
backend to propagate the signal handler function name to the C code
and provide the signal handler entry point to the runtime system.

I'm sure there are bugs remaining, in particular I am worried about
reentrancy of basis library, since I didn't think about that at all
when implementing it. 

In any case, I'll try to make a snapshot in the next week or so with
signals, the (type unsafe) serialization and deserialization, and all
the latest bugfixes.

--------------------------------------------------------------------------------

signature SIGNALS =
   sig
      eqtype signal

      type sigset

      val empty: sigset
      val full: sigset
      val add: sigset * signal -> sigset
      val del: sigset * signal -> sigset
      val isMember: sigset * signal -> bool
	 
      val block: sigset -> unit
      val unblock: sigset -> unit

      datatype handler =
	 Default
       | Ignore
       | Handler of unit -> unit
	 
      (* Get the current handler for a signal. *)
      val getHandler: signal -> handler
	 
      (* Set the handler for a signal. *)
      val setHandler: signal * handler -> unit
   end