Next: , Previous: Rendezvous base combinators, Up: Concurrent ML


5.4.4 Rendezvous communication channels

5.4.4.1 Synchronous channels

The rendezvous-channels structure provides a facility for synchronous channels: channels for communication between threads such that any receiver blocks until another thread sends a message, or any sender blocks until another thread receives the sent message. In CML, synchronous channels are also called merely `channels.'

— procedure: make-channel –> channel
— procedure: channel? object –> boolean

Make-channel creates and returns a new channel. Channel? is the disjoint type predicate for channels.

— procedure: send-rv channel message –> rendezvous
— procedure: send channel message –> unspecified (may block)

Send-rv returns a rendezvous that, when synchronized, becomes enabled when a reception rendezvous for channel is synchronized, at which point that reception rendezvous is enabled with a value of message. When enabled, the rendezvous returned by send-rv produces an unspecified value. Send is like send-rv, but it has the effect of immediately synchronizing the rendezvous, so it therefore may block, and it does not return a rendezvous; (send channel message) is equivalent to (sync (send-rv channel message)).

— procedure: receive-rv channel –> rendezvous
— procedure: receive channel –> value (may block)

Receive-rv returns a rendezvous that, when synchronized, and when a sender rendezvous for channel with some message is synchronized, becomes enabled with that message, at which point the sender rendezvous is enabled with an unspecified value. Receive is like receive-rv, but it has the effect of immediately synchronizing the reception rendezvous, so it therefore may block, and it does not return the rendezvous but rather the message that was sent; (receive channel) is equivalent to (sync (receive-rv channel)).

5.4.4.2 Asynchronous channels

The rendezvous-async-channels provides an asynchronous channel1 facility. Like synchronous channels, any attempts to read from an asynchronous channel will block if there are no messages waiting to be read. Unlike synchronous channels, however, sending a message will never block. Instead, a queue of messages or a queue of recipients is maintained: if a message is sent and there is a waiting recipient, the message is delivered to that recipient; otherwise it is added to the queue of messages. If a thread attempts to receive a message from an asynchronous channel and there is a pending message, it receives that message; otherwise it adds itself to the list of waiting recipients and then blocks.

Note: Operations on synchronous channels from the structure rendezvous-channels do not work on asynchronous channels.

— procedure: make-async-channel –> async-channel
— procedure: async-channel? obj –> boolean

Make-async-channel creates and returns an asynchronous channel. Async-channel? is the disjoint type predicate for asynchronous channels.

— procedure: receive-async-rv channel –> rendezvous
— procedure: receive-async channel –> value (may block)

Receive-async-rv returns a rendezvous that, when synchronized, becomes enabled when a message is available in channel's queue of messages. Receive-async has the effect of immediately synchronizing such a rendezvous and, when the rendezvous becomes enabled, returning the value itself, rather than the rendezvous; (receive-async channel) is equivalent to (sync (receive-async-rv channel)).

— procedure: send-async channel message –> unspecified

Sends a message to the asynchronous channel channel. Unlike the synchronous channel send operation, this procedure never blocks arbitrarily long.2 There is, therefore, no need for a send-async-rv like the send-rv for synchronous channels. If there is a waiting message recipient, the message is delivered to that recipient; otherwise, it is added to the channel's message queue.


Footnotes

[1] Known as mailboxes in Reppy's original CML.

[2] However, asynchronous channels are implemented by a thread that manages two synchronous channels (one for sends & one for receives), so this may block briefly if the thread is busy receiving other send or receive requests.