Runtime support for message passing with protocol enforcement.
Pipes consist of two endpoints. One endpoint can send messages and the other can receive messages. The set of legal messages and which directions they can flow at any given point are determined by a protocol. Below is an example protocol.
proto! pingpong (
ping: send {
ping -> pong
}
pong: recv {
pong -> ping
}
)
The proto!
syntax extension will convert this into a module called pingpong
, which includes a set of types and functions that can be used to write programs that follow the pingpong protocol.
RecvPacket
- Represents the receive end of a pipeSendPacket
- The sending end of a pipeBufferHeader
PacketHeader
RecvPacketBuffered
SendPacketBuffered
of ::core::cmp::Eq for State
for PacketHeader
of HasBuffer for Packet<T> where <T: Owned>
of ::ops::Drop for BufferResource<T> where <T>
of Selectable for *PacketHeader
of ::ops::Drop for SendPacketBuffered<T, Tbuffer> where <T: Owned, Tbuffer: Owned>
for SendPacketBuffered<T, Tbuffer> where <T, Tbuffer>
of ::ops::Drop for RecvPacketBuffered<T, Tbuffer> where <T: Owned, Tbuffer: Owned>
for RecvPacketBuffered<T, Tbuffer> where <T: Owned, Tbuffer: Owned>
of Selectable for RecvPacketBuffered<T, Tbuffer> where <T: Owned, Tbuffer: Owned>
BufferHeader
PacketHeader
RecvPacketBuffered
SendPacketBuffered
peek
- Returns true if messages are available.recv
- Receives a message from a pipe.select
- Waits on a set of endpointsselect2
- Receives a message from one of two endpoints.select2i
- Returns 0 or 1 depending on which endpoint is ready to receiveselecti
- Returns the index of an endpoint that is ready to receive.spawn_service
- Spawn a task to provide a service.spawn_service_recv
- Like spawn_service_recv
, but for protocols that start in the receive state.try_recv
- Attempts to receive a message from a pipe.wait_many
- Returns when one of the packet headers reports data is available.pipes::rt
RecvPacket
type RecvPacket<T> = RecvPacketBuffered<T, Packet<T>>
Represents the receive end of a pipe. It can receive exactly one message.
SendPacket
type SendPacket<T> = SendPacketBuffered<T, Packet<T>>
The sending end of a pipe. It can be used to send exactly one message.
BufferHeader
pub struct BufferHeader {
mut ref_count: int,
}
PacketHeader
pub struct PacketHeader {
mut state: State,
mut blocked_task: *rust_task,
mut buffer: *libc::c_void,
}
RecvPacketBuffered
pub struct RecvPacketBuffered<T, Tbuffer> {
mut p: Option<*Packet<T>>,
mut buffer: Option<BufferResource<Tbuffer>>,
}
SendPacketBuffered
pub struct SendPacketBuffered<T, Tbuffer> {
mut p: Option<*Packet<T>>,
mut buffer: Option<BufferResource<Tbuffer>>,
}
::core::cmp::Eq
for State
eq
fn eq(&self, __other: &State) -> bool
ne
fn ne(&self, __other: &State) -> bool
PacketHeader
mark_blocked
unsafe fn mark_blocked(&self, this: *rust_task) -> State
unblock
unsafe fn unblock(&self)
buf_header
unsafe fn buf_header(&self) -> ~BufferHeader
set_buffer
fn set_buffer<T: Owned>(&self, b: ~Buffer<T>)
HasBuffer
for Packet<T>
where <T: Owned>
set_buffer
fn set_buffer(&self, b: *libc::c_void)
::ops::Drop
for BufferResource<T>
where <T>
finalize
fn finalize(&self)
Selectable
for *PacketHeader
header
fn header(&self) -> *PacketHeader
::ops::Drop
for SendPacketBuffered<T, Tbuffer>
where <T: Owned, Tbuffer: Owned>
finalize
fn finalize(&self)
SendPacketBuffered<T, Tbuffer>
where <T, Tbuffer>
unwrap
fn unwrap(&self) -> *Packet<T>
header
fn header(&self) -> *PacketHeader
reuse_buffer
fn reuse_buffer(&self) -> BufferResource<Tbuffer>
::ops::Drop
for RecvPacketBuffered<T, Tbuffer>
where <T: Owned, Tbuffer: Owned>
finalize
fn finalize(&self)
RecvPacketBuffered<T, Tbuffer>
where <T: Owned, Tbuffer: Owned>
unwrap
fn unwrap(&self) -> *Packet<T>
reuse_buffer
fn reuse_buffer(&self) -> BufferResource<Tbuffer>
Selectable
for RecvPacketBuffered<T, Tbuffer>
where <T: Owned, Tbuffer: Owned>
header
fn header(&self) -> *PacketHeader
BufferHeader
fn BufferHeader() -> BufferHeader
PacketHeader
fn PacketHeader() -> PacketHeader
RecvPacketBuffered
fn RecvPacketBuffered<T, Tbuffer>(p: *Packet<T>) ->
RecvPacketBuffered<T, Tbuffer>
SendPacketBuffered
fn SendPacketBuffered<T, Tbuffer>(p: *Packet<T>) ->
SendPacketBuffered<T, Tbuffer>
peek
fn peek<T: Owned, Tb: Owned>(p: &RecvPacketBuffered<T, Tb>) -> bool
Returns true if messages are available.
recv
fn recv<T: Owned, Tbuffer: Owned>(p: RecvPacketBuffered<T, Tbuffer>) -> T
Receives a message from a pipe.
Fails if the sender closes the connection.
select
fn select<T: Owned, Tb: Owned>(endpoints: ~[RecvPacketBuffered<T, Tb>]) ->
(uint, Option<T>, ~[RecvPacketBuffered<T, Tb>])
Waits on a set of endpoints. Returns a message, its index, and a list of the remaining endpoints.
select2
fn select2<A: Owned, Ab: Owned, B: Owned,
Bb: Owned>(a: RecvPacketBuffered<A, Ab>,
b: RecvPacketBuffered<B, Bb>) ->
Either<(Option<A>, RecvPacketBuffered<B, Bb>),
(RecvPacketBuffered<A, Ab>, Option<B>)>
Receives a message from one of two endpoints.
The return value is left
if the first endpoint received something, or right
if the second endpoint receives something. In each case, the result includes the other endpoint as well so it can be used again. Below is an example of using select2
.
match select2(a, b) {
left((none, b)) {
// endpoint a was closed.
}
right((a, none)) {
// endpoint b was closed.
}
left((Some(_), b)) {
// endpoint a received a message
}
right(a, Some(_)) {
// endpoint b received a message.
}
}
Sometimes messages will be available on both endpoints at once. In this case, select2
may return either left
or right
.
select2i
fn select2i<A: Selectable, B: Selectable>(a: &A, b: &B) -> Either<(), ()>
Returns 0 or 1 depending on which endpoint is ready to receive
selecti
fn selecti<T: Selectable>(endpoints: &[T]) -> uint
Returns the index of an endpoint that is ready to receive.
spawn_service
fn spawn_service<T: Owned,
Tb: Owned>(init:
extern "Rust" fn()
->
(SendPacketBuffered<T, Tb>,
RecvPacketBuffered<T, Tb>),
service: ~fn(v: RecvPacketBuffered<T, Tb>)) ->
SendPacketBuffered<T, Tb>
Spawn a task to provide a service.
It takes an initialization function that produces a send and receive endpoint. The send endpoint is returned to the caller and the receive endpoint is passed to the new task.
spawn_service_recv
fn spawn_service_recv<T: Owned,
Tb: Owned>(init:
extern "Rust" fn()
->
(RecvPacketBuffered<T, Tb>,
SendPacketBuffered<T, Tb>),
service: ~fn(v: SendPacketBuffered<T, Tb>))
-> RecvPacketBuffered<T, Tb>
Like spawn_service_recv
, but for protocols that start in the receive state.
try_recv
fn try_recv<T: Owned, Tbuffer: Owned>(p: RecvPacketBuffered<T, Tbuffer>) ->
Option<T>
Attempts to receive a message from a pipe.
Returns None
if the sender has closed the connection without sending a message, or Some(T)
if a message was received.
wait_many
fn wait_many<T: Selectable>(pkts: &[T]) -> uint
Returns when one of the packet headers reports data is available.
This function is primarily intended for building higher level waiting functions, such as select
, select2
, etc.
It takes a vector slice of packet_headers and returns an index into that vector. The index points to an endpoint that has either been closed by the sender or has a message waiting to be received.