[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