[MLton-user] signal handling an mllex based filter

Michael Norrish Michael.Norrish at nicta.com.au
Tue Aug 4 17:21:59 PDT 2009


Wesley W. Terpstra wrote:

> Sounds like a reasonable approach. There is no way to raise an
> exception in one thread from another, so you cannot interrupt the
> running lexer.

Right.  (Poly/ML provides a command to raise Interrupt in all running
threads, so that's what I did there.  It's a nice convenience.)

Anyway, the approach did work, which was gratifying.

For the sake of posterity, there is one error in what I wrote
initially. I claimed that it was enough to do

     val lexer = filter.makeLexer (read_from_stream instream) state

and then repeatedly call

     lexer()

after interruptions.  In fact, the call to makeLexer sets up a MLLex
generated lexer and initialises the internal state variable, so when
you are switching to a fresh slave you need to call

   filter.makeLexer ...

again, rather than just lexer().  Otherwise, you will just inherit the
old internal state.

Also, there is no need for a separate master thread: the handler can
just create fresh slaves and switch to them directly.  My code now
looks like:

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

...

fun slave() = let
   val lexer = filter.makeLexer (read_from_stream instream) state
in
   lexer();
   TextIO.closeOut outstream;
   exit success
end

open MLton.Thread

fun interrupt_handler _ = let
   open filter.UserDeclarations
in
   ... reset state's reference variables ...
   prepare (new slave, ())
end

val h = MLton.Signal.Handler.handler interrupt_handler
val _ = MLton.Signal.setHandler(Posix.Signal.int, h)

val _ = switch (fn _ => prepare (new slave, ()))
----------------------------------------------------------------------

The thread-specific code is nice and short.

Best,
Michael.



More information about the MLton-user mailing list