# The Concurrent ML Reference Manual

## The `SyncVar` structure

#### Synopsis

> `signature `SYNC_VAR`
> structure `SyncVar` : SYNC_VAR
> `

The SyncVar structure provides Id-style synchronous variables (or memory cells). These variables have two states: empty and full. An attempt to read a value from an empty variable blocks the calling thread until there is a value available. An attempt to put a value into a variable that is full results in the Put exception being raised. There are two kinds of synchronous variables: I-variables are write-once, while M-variables are mutable.

#### Interface

> `exception Put
> type 'a ivar
> val iVar : unit -> 'a ivar
> val iPut : ('a ivar * 'a) -> unit
> val iGet : 'a ivar -> 'a
> val iGetEvt : 'a ivar -> 'a event
> val iGetPoll : 'a ivar -> 'a option
> val sameIVar : ('a ivar * 'a ivar) -> bool
> type 'a mvar
> val mVar : unit -> 'a mvar
> val mVarInit : 'a -> 'a mvar
> val mPut : ('a mvar * 'a) -> unit
> val mTake : 'a mvar -> 'a
> val mTakeEvt : 'a mvar -> 'a event
> val mGet : 'a mvar -> 'a
> val mGetEvt : 'a mvar -> 'a event
> val mTakePoll : 'a mvar -> 'a option
> val mGetPoll : 'a mvar -> 'a option
> val mSwap : ('a mvar * 'a) -> 'a
> val mSwapEvt : ('a mvar * 'a) -> 'a event
> val sameMVar : ('a mvar * 'a mvar) -> bool
> `

#### Description

`exception Put`
  This exception is raised when an attempt is made to put a value into a value that is already full (see iPut and mPut).
`type 'a ivar`
  This is the type constructor for I-structured variables. I-structured variables are write-once variables that provide synchronization on read operations. They are especially useful for one-shot communications, such as reply messages in client/server protocols, and can also be used to implement shared incremental data structures.
`iVar ()`
  creates a new empty I-variable.
`iPut (iv, x)`
  fills the I-variable iv with the value x. Any threads that are blocked on iv will be resumed. If iv already has a value in it, then the Put exception is raised.
`iGet iv`
  returns the contents of the I-variable iv. If the variable is empty, then the calling thread blocks until the variable becomes full.
`iGetEvt iv`
  returns an event-value that represents the iGet operation on iv.
`val iGetPoll`
  This is a non-blocking version of iGet. If the corresponding blocking form would block, then it returns NONE; otherwise it returns SOME of the variable's contents.
`sameIVar (iv1, iv2)`
  returns `true`, if iv1 and iv2 are the same I-variable.
`type 'a mvar`
  This is the type constructor for M-structured variables. Unlike ivar values, M-structured variables may be updated multiple times. Like I-variables, however, they may only be written if they are empty.
`mVar ()`
  creates a new empty M-variable.
`mVarInit x`
  creates a new M-variable initialized to x.
`mPut (mv, x)`
  fills the M-variable mv with the value x. Any threads that are blocked on mv will be resumed. If mv already has a value in it, then the Put exception is raised.
`mTake mv`
  removes and returns the contents of the M-variable mv making it empty. If the variable is already empty, then the calling thread is blocked until a value is available.
`mTakeEvt mv`
  returns an event-value that represents the mTake operation on mv.
`mGet mv`
  returns the contents of the M-variable mv without emptying the variable; if the variable is empty, then the thread blocks until a value is available. It is equivalent to the code:

      let val x = mTake mv in mPut(mv, x); x end

`mGetEvt mv`
  returns an event-value that represents the mGet operation on mv.
`val mTakePoll`
`val mGetPoll`
  These are non-blocking versions of mTake and mGet (respectively). If the corresponding blocking form would block, then they return NONE; otherwise they return SOME of the variable's contents.
`mSwap (mv, newV)`
  puts the value newV into the M-variable mv and returns the previous contents. If the variable is empty, then the thread blocks until a value is available. It is equivalent to the code:

      let val x = mTake mv in mPut(mv, newV); x end

  except that `mSwap` is executed atomically.
`mSwapEvt (mv, newV)`
  returns an event-value that represents the mSwap operation on mv and newV.
`sameMVar (mv1, mv2)`
  returns `true`, if mv1 and mv2 are the same M-variable.

#### See Also

> CML

#### Discussion

I-variables provide a useful mechanism for implementing the reply communication in request/reply protocols (in cases where the server does not care if the reply is accepted). They may also be used to implement incremental data structures and streams; for example, the Multicast structure uses I-variables to implement its multicast channels.

A disciplined use of M-variables can provide an atomic read-modify-write operation.

[ Top | Parent | Contents | Index | Root ]

Last Modified &date;
Comments to John Reppy.
Copyright © 1998 Bell Labs, Lucent Technologies