Up

Module Mvar

An Mvar is a mutable location that is either empty or contains a value. One can put or set the value, and wait on value_available for the location to be filled in either way.

Having an Mvar.Writer.t gives the capability to mutate the mvar.

The key difference between an Mvar and an Ivar is that an Mvar may be filled multiple times.

This implementation of Mvar also allows one to replace the value without any guarantee that the reading side has seen it. This is useful in situations where last-value semantics are desired (i.e. you want to signal whenever a config file is updated, but only care about the most recent values).

A Mvar can also be used as a baton passing mechanism between a producer and consumer. For instance, a producer reading from a socket and producing a set of deserialized messages can put the batch from a single read into an Mvar and can wait for taken to return as a pushback mechanism. The consumer meanwhile waits on value_available. This way the natural batch size is passed between the two sub-systems with minimal overhead.

Signature

type ('a, 'phantom) t
val sexp_of_t : ('a -> Sexplib.Sexp.t) -> ('phantom -> Sexplib.Sexp.t) -> ('a, 'phantom) t -> Sexplib.Sexp.t
module Read_write : sig .. end
module Read_only : sig .. end
val create : unit -> 'a Read_write.t
val is_empty : (_, _) t -> bool
val put : 'a Read_write.t -> 'a -> unit Import.Deferred.t

put t a waits until is_empty t, and then does set t a. If there are multiple concurrent puts, there is no fairness guarantee (i.e. puts may happen out of order or may be starved).

val set : 'a Read_write.t -> 'a -> unit

set t a sets the value in t to a, even if not (is_empty t). This is useful if you want takers to have last-value semantics.

val read_only : 'a Read_write.t -> 'a Read_only.t
val value_available : _ Read_only.t -> unit Import.Deferred.t

value_available t returns a deferred d that becomes determined when a value is in t. d does not include the value in t because that value may change after d becomes determined and before a deferred bind on d gets to run.

Repeated calls to value_available will always return the same deferred until take returns Some.

val take : 'a Read_only.t -> 'a option

take t returns the value in t and clears t, or returns None if is_empty t. take_exn is like take, except it raises if is_empty t.

val take_exn : 'a Read_only.t -> 'a
val taken : (_, _) t -> unit Import.Deferred.t

taken t returns a deferred that is filled the next time take clears t.

val peek : ('a, _) t -> 'a option

peek t returns the value in t without clearing t, or returns None is is_empty t. peek_exn t is like peek, except it raises if is_empty t.

val peek_exn : ('a, _) t -> 'a