last update:2009-01-16

event primitives

In concurrent cell, there are three new event primitives on Event module.

  • with_nack : (unit event -> 'a event) -> 'a event
    • a guard event primitive with nack unit event. If the unit event synchronization success, it's mean the guard event is not selected. Similar to wrap_abort.
  • never : 'a -> 'a event
    • an event will be never synchronized.
  • future: : ('a -> 'b) -> 'a -> 'b event


Ivar is immutable inter-thread variable. Once a value is putted into the ivar, no one can take or rewrite that value. This variable is convenient to one-shot communication.

Most common case of using the ivar is to replay an answer from server to client. These style allowed us to 'select' the replay event.

 (* client thread request. this event is selectable. *)
 guard (fun () ->
   let ivar = Ivar.make () in
   sync (send server (reqest, ivar)); ivar)

 (* sever thread answer *)
 let reqest, ivar = sync (receive ch) in
 let answer = do_something request in
 sync (Ivar.put ivar answer) (* this operation immediately success *)

Note if you put a value into the full ivar, Full exception will be raised.


Mvar is mutable inter-thread variable. There are put, take, read and replace operations over the mvar.

  • Put operation puts a value into the mvar. That mvar will be full.
  • Read operation reads a value from the mvar.
  • Take operation takes a value from the mvar. That mvar will be empty.
  • Replace operation takes a value from the mvar and re-put the modified value into the mvar. All operation over that mvar will be blocked until the replace operation finish.
  • If the mvar is empty, put operation immediately success. read, take and replace operations are blocked.
  • If the mvar is full, read, take, replace operations immediately success. put operation is blocked.

Here is a signature of Mvar module.

type 'a t (* the mvar *)
val make : unit -> 'a t
val init_make : 'a -> 'a t (* initialy full *)
val read : 'a t -> 'a Event.event
val take : 'a t -> 'a Event.event
val put : 'a t -> 'a -> unit Event.event
val replace : 'a t -> ('a -> 'a) -> unit Event.event


Mbox is a inter-thread queue(FIFO). There are push, pop, pop_all operations over the mbox. This structure introduce asynchronous communication into the synchronous scheme.

  • Push operation puts a value into the mbox.
  • Push operation always success immediately. (in term of enough memory).
  • Pop operation pop a value from the mbox.
  • If the mbox is empty, pop operation is blocked.
  • Pop_all operation pop the all values from the mbox. The mbox is empty, empty list is returned.


Bcast module is the most useful module in concurrent cell.

type 'a t
type 'a port
val make : unit -> 'a t
val send : 'a t -> 'a -> unit
val receive : 'a t -> 'a event
val make_port : 'a t -> 'a port (* make buffered broadcast channel *)
val receive_port : 'a port -> 'a event (* receive with buffer *)
Here is a simple example with Bcast. Chat daemon. You can find how to use concurrent cell with the network related functions.