Files
tokio/src/channel.rs
T

109 lines
3.5 KiB
Rust
Raw Normal View History

2016-09-02 11:07:52 -07:00
//! In-memory evented channels.
//!
//! This module contains a `Sender` and `Receiver` pair types which can be used
//! to send messages between different future tasks.
2016-08-20 23:41:19 -07:00
use std::io;
use std::sync::mpsc::TryRecvError;
2016-09-07 16:11:19 -07:00
use futures::{Poll, Async};
2016-08-22 10:10:03 -07:00
use futures::stream::Stream;
2016-08-20 23:41:19 -07:00
use mio::channel;
2016-09-02 11:07:52 -07:00
use reactor::{Handle, PollEvented};
2016-08-20 23:41:19 -07:00
/// The transmission half of a channel used for sending messages to a receiver.
///
/// A `Sender` can be `clone`d to have multiple threads or instances sending
/// messages to one receiver.
///
2016-09-08 10:33:41 -04:00
/// This type is created by the [`channel`] function.
///
/// [`channel`]: fn.channel.html
2016-08-20 23:41:19 -07:00
pub struct Sender<T> {
tx: channel::Sender<T>,
}
/// The receiving half of a channel used for processing messages sent by a
/// `Sender`.
///
2016-08-22 10:10:03 -07:00
/// A `Receiver` cannot be cloned, so only one thread can receive messages at a
/// time.
2016-08-20 23:41:19 -07:00
///
2016-09-08 10:33:41 -04:00
/// This type is created by the [`channel`] function and implements the
/// `Stream` trait to represent received messages.
///
/// [`channel`]: fn.channel.html
2016-08-20 23:41:19 -07:00
pub struct Receiver<T> {
2016-09-02 11:07:52 -07:00
rx: PollEvented<channel::Receiver<T>>,
2016-08-20 23:41:19 -07:00
}
2016-09-02 11:07:52 -07:00
/// Creates a new in-memory channel used for sending data across `Send +
/// 'static` boundaries, frequently threads.
///
/// This type can be used to conveniently send messages between futures.
/// Unlike the futures crate `channel` method and types, the returned tx/rx
/// pair is a multi-producer single-consumer (mpsc) channel *with no
/// backpressure*. Currently it's left up to the application to implement a
/// mechanism, if necessary, to avoid messages piling up.
///
/// The returned `Sender` can be used to send messages that are processed by
/// the returned `Receiver`. The `Sender` can be cloned to send messages
/// from multiple sources simultaneously.
2016-09-07 16:11:19 -07:00
pub fn channel<T>(handle: &Handle) -> io::Result<(Sender<T>, Receiver<T>)>
2016-09-02 11:07:52 -07:00
where T: Send + 'static,
{
let (tx, rx) = channel::channel();
2016-09-07 16:11:19 -07:00
let rx = try!(PollEvented::new(rx, handle));
Ok((Sender { tx: tx }, Receiver { rx: rx }))
2016-08-20 23:41:19 -07:00
}
impl<T> Sender<T> {
/// Sends a message to the corresponding receiver of this sender.
///
/// The message provided will be enqueued on the channel immediately, and
/// this function will return immediately. Keep in mind that the
/// underlying channel has infinite capacity, and this may not always be
/// desired.
///
/// If an I/O error happens while sending the message, or if the receiver
/// has gone away, then an error will be returned. Note that I/O errors here
/// are generally quite abnormal.
pub fn send(&self, t: T) -> io::Result<()> {
self.tx.send(t).map_err(|e| {
match e {
channel::SendError::Io(e) => e,
channel::SendError::Disconnected(_) => {
io::Error::new(io::ErrorKind::Other,
"channel has been disconnected")
}
}
})
}
}
impl<T> Clone for Sender<T> {
fn clone(&self) -> Sender<T> {
Sender { tx: self.tx.clone() }
}
}
2016-08-22 10:10:03 -07:00
impl<T> Stream for Receiver<T> {
type Item = T;
type Error = io::Error;
fn poll(&mut self) -> Poll<Option<T>, io::Error> {
2016-09-02 11:07:52 -07:00
if let Async::NotReady = self.rx.poll_read() {
return Ok(Async::NotReady)
}
2016-08-20 23:41:19 -07:00
match self.rx.get_ref().try_recv() {
2016-09-01 16:42:48 -07:00
Ok(t) => Ok(Async::Ready(Some(t))),
2016-08-20 23:41:19 -07:00
Err(TryRecvError::Empty) => {
self.rx.need_read();
2016-09-01 16:42:48 -07:00
Ok(Async::NotReady)
2016-08-20 23:41:19 -07:00
}
2016-09-01 16:42:48 -07:00
Err(TryRecvError::Disconnected) => Ok(Async::Ready(None)),
2016-08-20 23:41:19 -07:00
}
}
}