Module IVar


module IVar: sig .. end
One-shot interprocess exceptions and variables.


Interprocess Exceptions


val with_interprocess_protect : (((unit -> 'a) -> 'a) -> 'b) -> 'b
Relay exceptions from a subprocess. with_interprocess_protect kont calls kont with one argument, protect: (unit -> 'a) -> 'a.

The function kont must fork into an observer process and an observed process. The observed process must not return from the call to kont; it must, however, call protect thunk exactly once with some thunk, which protect will call. When kont returns in the observer process, it blocks until the thunk returns. If the thunk returns normally (or execs, or exits), then protect thunk returns the result of the thunk in the observed process, and with_interprocess_protect returns the result of kont in the observer process. However, if the thunk raises an exception, then the observed process terminates with status 2 and the call to with_interprocess_protect in the observer returns abnormally by re-raising the exception.

In this example, if Proc.exec raises an exception in the child process, then with_interprocess_protect will re-raise that exception in the parent process:

  with_interprocess_protect
    (fun protect ->
       match Proc.fork () with
       | None     ->
           protect (fun () -> Proc.exec prog args);
           exit 3 (* can't happen *)
       | Some proc -> proc)

val with_interprocess_raise_and_okay : ((exn -> unit) -> (unit -> unit) -> 'a) -> 'a
Relay exceptions from another process. with_interprocess_raise_and_okay kont calls kont with two arguments, { oops : exn -> unit okay : unit -> unit }

The function kont must fork into an observed process and an observer process. When the call to kont returns in the observer process, with_interprocess_raise_and_okay then waits for either oops or okay to be called in the observed process. If okay () is called, then it returns the result of kont; if oops e is called, then it instead raises the exception e in the observer process. If the observed process fails to call either oops or okay, then the observer process will block indefinitely.


Interprocess Variables


type 'a read_end 
The read-end of an interprocess variable.
type 'a write_end 
The write-end of an interprocess variable.
exception Dead
Raised on attempts to re-use an IVar. IVars allow (require, in fact) exactly one read and one write.
val create : unit -> 'a read_end * 'a write_end
Create a channel pair (r, w). The protocol is then as follows. One process must execute: This operation will block, until another process does one of: The IVar.write call may or may not block, depending on the underlying implementation. In any case, it is imperative that read happens in a separate process from the write/close/exec/exit, or the program may block indefinitely.
val read : 'a read_end -> 'a option
Read an 'a option from an IVar. Blocks until the associated IVar.write_end is written or closed. If x is written on the other end, returns Some x; if the other end is closed (including by exit or exec), returns None.
val write : 'a write_end -> 'a -> unit
Write to an IVar.
val close : 'a write_end -> unit
Close an IVar without writing.