Portability | portable |
---|---|
Stability | provisional |
Maintainer | ben.franksen@online.de |
Events and Channels as in Concurrent ML (extended with communication guards)
See A Concurrent ML Library in Concurrent Haskell by Avik Chaudhuri (avik@cs.ucsc.edu). The original code as well as the papers can be found at http://www.cs.umd.edu/~avik/projects/cmllch/.
- data Channel a
- channel :: IO (Channel a)
- receive :: Channel a -> (a -> Bool) -> Event a
- transmit :: Channel a -> a -> Event ()
- data Event a
- sync :: Event a -> IO a
- choose :: [Event a] -> Event a
- wrap :: Event a -> (a -> IO b) -> Event b
- guard :: IO (Event a) -> Event a
- wrapabort :: IO () -> Event a -> Event a
- spawn :: IO () -> IO ThreadId
Channels
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.
Values of type a
can be transported over channels of type Channel a
.
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
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).
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.
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.