cml-0.1.1: Events and Channels as in Concurrent ML





Events and Channels as in Concurrent ML (extended with communication guards)

See A Concurrent ML Library in Concurrent Haskell by Avik Chaudhuri ( The original code as well as the papers can be found at



Channels transport a single value at a time. The operations on channels are: creation, transmit, and receive. None of them block the calling thread, in fact transmit and receive are pure functions, not IO actions. Blocking may occur only when a thread explicitly synchronizes on the resulting event.

data Channel a Source

Values of type a can be transported over channels of type Channel a.

channel :: IO (Channel a)Source

Create a new channel.

receive :: Channel a -> (a -> Bool) -> Event aSource

Receive a message from a channel.

More precisely, receive c cond returns an event that, on synchronization, accepts a message m on channel c and returns m. The resulting event is eligible for synchronization with a transmit c m only if cond m is true.

transmit :: Channel a -> a -> Event ()Source

Transmit a message over a channel.

More precisely, transmit c m returns an event that, on synchronization, sends the message m on channel c and returns (). Such an event must synchronize with receive c.


Events encapsulate a potentially blocking point of synchronization between threads, together with possible pre- and post-synchronization code as well as code that is executed (in a separate thread) when an event is not selected (aborted).

data Event a Source

Events return a value on synchronization.

Note that by construction, an event can synchronize at exactly one commit point, where a message is either sent or accepted on a channel. This commit point may be selected among several other, potential commit points. Some code may be run before synchronization, as specified by guard functions throughout the event. Some more code may be run after synchronization, as specified by wrap functions that surround the commit point, and by wrapabort functions that do not surround the commit point.

sync :: Event a -> IO aSource

Synchronize an event.

This blocks the calling thread until a matching event is available.

choose :: [Event a] -> Event aSource

Non-deterministically select an event from a list of events, so that the selected event can be synchronized. The other events in the list are aborted.

wrap :: Event a -> (a -> IO b) -> Event bSource

Specify a post-synchronization action.

More precisely, wrap v f returns an event that, on synchronization, synchronizes the event v and then runs the action returned by f applied to the result.

guard :: IO (Event a) -> Event aSource

Specify a pre-synchronization action.

More precisely, guard a returns an event that, on synchronization, synchronizes the event returned by the action a. Here, a is run every time a thread tries to synchronize guard a.

wrapabort :: IO () -> Event a -> Event aSource

Specify a post-synchronization action that is spawned if an event is not selected by a choose.

More precisely, wrapabort a v returns an event that, on synchronization, synchronizes the event v, and on abortion, spawns a thread that runs the action a. Here, if v itself is of the form choose vs and one of the events in vs is selected, then v is considered selected, so a is not spawned.

spawn :: IO () -> IO ThreadIdSource

A synonym for forkIO.