diff --git a/src/libsync/comm/duplex.rs b/src/libsync/comm/duplex.rs index 3840e55bb424d..ca27975be1e5d 100644 --- a/src/libsync/comm/duplex.rs +++ b/src/libsync/comm/duplex.rs @@ -14,20 +14,32 @@ Higher level communication abstractions. */ -#![allow(missing_doc)] - use core::prelude::*; use comm; use comm::{Sender, Receiver, channel}; -/// An extension of `pipes::stream` that allows both sending and receiving. +/// An extension of `pipes::stream` that allows both sending and receiving +/// data over two channels pub struct DuplexStream { tx: Sender, rx: Receiver, } /// Creates a bidirectional stream. +/// +/// # Example +/// ``` +/// use std::comm; +/// +/// let (left, right) = comm::duplex(); +/// +/// left.send(("ABC").to_string()); +/// right.send(123); +/// +/// assert!(left.recv() == 123); +/// assert!(right.recv() == "ABC".to_string()); +/// ``` pub fn duplex() -> (DuplexStream, DuplexStream) { let (tx1, rx1) = channel(); let (tx2, rx2) = channel(); @@ -37,18 +49,76 @@ pub fn duplex() -> (DuplexStream, DuplexStream) { // Allow these methods to be used without import: impl DuplexStream { + /// Sends a value along this duplex to be received by the corresponding + /// receiver. + /// + /// Rust duplexes are infinitely buffered so this method will never block. + /// + /// # Failure + /// + /// This function will fail if the other end of the duplex has hung up. + /// This means that if the corresponding receiver has fallen out of scope, + /// this function will trigger a fail message saying that a message is being + /// sent on a closed duplex. + /// + /// Note that if this function does not fail, it does not mean that the data + /// will be successfully received. All sends are placed into a queue, so it + /// is possible for a send to succeed (the other end is alive), but then the + /// other end could immediately disconnect. + /// + /// The purpose of this functionality is to propagate failure among tasks. + /// If failure is not desired, then consider using the send_opt method. pub fn send(&self, x: S) { self.tx.send(x) } + + /// Optionally send data to the channel. + /// + /// # Example + /// ``` + /// use std::comm; + /// + /// let (left, right) = comm::duplex(); + /// + /// left.send("ABC".to_string()); + /// right.send(123); + /// assert!(right.recv() == "ABC".to_string()); + /// drop(right); + /// assert!(left.recv() == 123); + /// assert_eq!(left.send_opt("ABC".to_string()), Err("ABC".to_string())); + /// ``` pub fn send_opt(&self, x: S) -> Result<(), S> { self.tx.send_opt(x) } + + /// Receive data from the channel. pub fn recv(&self) -> R { self.rx.recv() } + + /// Try to receive data from the channel. + /// + /// # Example + /// ``` + /// use std::comm; + /// + /// let (left, right) = comm::duplex(); + /// let a = "ABC".to_string(); + /// let b:u32 = 123; + /// + /// left.send(a.clone()); + /// assert_eq!(right.recv(), a); + /// right.send(b); + /// assert_eq!(left.recv(), b); + /// // Here the channel is empty so it return an error. + /// assert_eq!(left.try_recv(), Err(comm::Empty)); + /// ``` +} pub fn try_recv(&self) -> Result { self.rx.try_recv() } + + /// Optionally receive data from the channel. pub fn recv_opt(&self) -> Result { self.rx.recv_opt() }