asynchronous exceptions
Stephen Weeks
MLton@sourcelight.com
Thu, 27 Jul 2000 11:18:45 -0700 (PDT)
> > (2) good
> > - handlers get to clean up when f() times out
>
> I'm not sure why you wouldn't say that (1) also has this option.
Because the thread that is evaluating f() gets thrown away. So, if an
outstream opened by f, it won't get closed.
> Even if
> f() runs in a different thread, doesn't the 'a option get returned to the
> thread that calls timeLimit(t, f)?
Yes.
> Of course, if the current thread is
> waiting for timeLimit to return, why does f() need to run in a separate
> thread at all?
So the signal handler that is waiting for the alarm can do something
sensible -- i.e. drop the current running thread (f()) and return to
the original thread waiting for f(). I couldn't think of another way
to do it, without asynchronous exceptions.
I'm still heavily leaning towards (1). Here's my current
implementation.
fun timeLimit(t: Time.t, f: unit -> 'a): 'a option =
let
val which = Itimer.Real
val signal = Itimer.whichSignal which
val res =
Thread.switch
(fn cur: 'a option Thread.t =>
let
fun handler _ = Thread.prepend(cur, fn () => NONE)
val _ = Handler.set(signal, Handler.Handler handler)
val _ = Itimer.set{which = which,
value = t,
interval = Time.zero}
val t = Thread.new(fn () =>
let
val res =
let val x = f()
in fn () => SOME x
end handle e => fn () => raise e
in Thread.switch'(fn _ => (cur, res))
end)
in (t, ())
end)
in Handler.set(signal, Handler.Default)
; res
end