Thanks for all your answers! I really appreciated the Gc.create_alarm hack, which does the job alright for now, but is quite imprecise. I have submitted a feature request for addition to the standard library [1], we'll see...

Cheers,

Samuel.

[1] http://caml.inria.fr/mantis/view.php?id=5908


On Wed, Jan 23, 2013 at 4:03 PM, Gerd Stolpmann <info@gerd-stolpmann.de> wrote:
Am 22.01.2013 19:57:15 schrieb(en) Samuel Mimram:

Hi,

I would like to implement a "timeout" function of type:

float -> ('a -> 'b) -> 'a -> 'b option

which takes a maximum number n of seconds to run, a function f, an argument
x, and returns Some (f x) if the computation ends before n seconds and None
otherwise. Of course, there is a simple implementation using
Unix.setitimer, but apparently it does not work under windows because of
signals implementation (and I don't have access to a windows machine...).
Since this is a pretty standard idom I expected to find it implemented in
some library, but could not find one. Also, I'd rather not heavily change
the code (i.e. monadic threads are not really an option here, and a small
function would be appreciated).

I think this is not possible without changes in the OCaml runtime - what we would need here is an emulation of signals under Windows, so that a timer thread could be started that finally sends the signal to the compute thread. However, such an emulation would be limited to pure computations, and would not be able to interrupt system calls (no support from Windows).

As long as you know that your compute functions allocate memory, it will do garbage collections, and you could set a GC hook:


exception Timeout

let timer tmo f x =
  let t0 = Unix.gettimeofday() in
  let alarm = ref None in
  Gc.major();
  try
    let al =
      Gc.create_alarm
        (fun () ->
           let t1 = Unix.gettimeofday() in
           if t1 -. t0 > tmo then raise Timeout
        ) in
    alarm := Some al;
    let r = f x in
    Gc.delete_alarm al;
    alarm := None;
    Some r
  with Timeout ->
    ( match !alarm with
        | Some al -> Gc.delete_alarm al
        | None -> ()
    );
    None

But this does not work if the function does not allocate enough memory (and also note that there are several race conditions in "timer").


Extra points if your solution also works with js_of_ocaml! :)

I don't think that there is any support in js_of_ocaml for completely asynchronous events (i.e. something like the regular check for signals the standard runtime does).

Gerd


Thanks!

Regards,

Samuel.

--
Caml-list mailing list.  Subscription management and archives:
https://sympa.inria.fr/sympa/arc/caml-list
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs



--
------------------------------------------------------------
Gerd Stolpmann, Darmstadt, Germany    gerd@gerd-stolpmann.de
Creator of GODI and camlcity.org.
Contact details:        http://www.camlcity.org/contact.html
Company homepage:       http://www.gerd-stolpmann.de
------------------------------------------------------------