Doc improvements (#46)

* small doc cleanups in PollEvented

* small doc cleanups in IoToken

* improve crate level documentation

- Add links to the futures, mio and tokio-uds crates.
- Add links to various structs and types mentioned.
- use eprintln for error reporting in the example.

* improvements to the UdpSocket documentation

- Fixed links usage.
- Removed references to a no longer existing `Window` struct.
- Made notes about using functions in context of a future.

* documentation improvements to UdpFramed and UdpCodec

- Since HTTP uses TCP (QUIC aside) using it as an example in an UDP
protocol feels wrong.
- Make the note of tampering with the underlying streams more explicit.

* update reactor module level documentation

Adds an explanation of every public struct.

* expand Handle and Remote documentation

* expand net module documentation

Adds an explanation of every public struct and how they work together.

* update TcpListener documentation

Reorder the various option methods; get first then set.
Note about panicing added to poll_read.

* remove mention of none-existing future R

* improve documentation of TcpStream

* fix UdpSocket doc

This when wrong when merging various commits.
This commit is contained in:
Thomas de Zeeuw 2017-12-05 16:55:25 +01:00 committed by Alex Crichton
parent 0b54557796
commit c801584d24
8 changed files with 289 additions and 176 deletions

View File

@ -1,21 +1,28 @@
//! `Future`-powered I/O at the core of Tokio
//!
//! This crate uses the `futures` crate to provide an event loop ("reactor
//! This crate uses the [`futures`] crate to provide an event loop ("reactor
//! core") which can be used to drive I/O like TCP and UDP. All asynchronous I/O
//! is powered by the `mio` crate.
//! is powered by the [`mio`] crate.
//!
//! [`futures`]: ../futures/index.html
//! [`mio`]: ../mio/index.html
//!
//! The concrete types provided in this crate are relatively bare bones but are
//! intended to be the essential foundation for further projects needing an
//! event loop. In this crate you'll find:
//!
//! * TCP, both streams and listeners
//! * UDP sockets
//! * An event loop to run futures
//! * TCP, both streams and listeners.
//! * UDP sockets.
//! * An event loop to run futures.
//!
//! More functionality is likely to be added over time, but otherwise the crate
//! is intended to be flexible, with the `PollEvented` type accepting any
//! type that implements `mio::Evented`. For example, the `tokio-uds` crate
//! uses `PollEvented` to provide support for Unix domain sockets.
//! is intended to be flexible, with the [`PollEvented`] type accepting any
//! type that implements [`mio::Evented`]. For example, the [`tokio-uds`] crate
//! uses [`PollEvented`] to provide support for Unix domain sockets.
//!
//! [`PollEvented`]: ./reactor/struct.PollEvented.html
//! [`mio::Evented`]: ../mio/event/trait.Evented.html
//! [`tokio-uds`]: https://crates.io/crates/tokio-uds
//!
//! Some other important tasks covered by this crate are:
//!
@ -45,40 +52,41 @@
//! use tokio::reactor::Core;
//!
//! fn main() {
//! // Create the event loop that will drive this server
//! // Create the event loop that will drive this server.
//! let mut core = Core::new().unwrap();
//! let handle = core.handle();
//!
//! let pool = CpuPool::new_num_cpus();
//!
//! // Bind the server's socket
//! // Bind the server's socket.
//! let addr = "127.0.0.1:12345".parse().unwrap();
//! let listener = TcpListener::bind(&addr, &handle).unwrap();
//! let listener = TcpListener::bind(&addr, &handle)
//! .expect("unable to bind TCP listener");
//!
//! // Pull out a stream of sockets for incoming connections
//! let server = listener.incoming().for_each(|(sock, _)| {
//! // Split up the reading and writing parts of the
//! // socket
//! // socket.
//! let (reader, writer) = sock.split();
//!
//! // A future that echos the data and returns how
//! // many bytes were copied...
//! let bytes_copied = copy(reader, writer);
//!
//! // ... after which we'll print what happened
//! // ... after which we'll print what happened.
//! let handle_conn = bytes_copied.map(|amt| {
//! println!("wrote {:?} bytes", amt)
//! }).map_err(|err| {
//! println!("IO error {:?}", err)
//! eprintln!("IO error {:?}", err)
//! });
//!
//! // Spawn the future as a concurrent task
//! // Spawn the future as a concurrent task.
//! pool.execute(handle_conn).unwrap();
//!
//! Ok(())
//! });
//!
//! // Spin up the server on the event loop
//! // Spin up the server on the event loop.
//! core.run(server).unwrap();
//! }
//! ```

View File

@ -1,7 +1,42 @@
//! TCP/UDP bindings for `tokio-core`
//! TCP/UDP bindings for `tokio`.
//!
//! This module contains the TCP/UDP networking types, similar to the standard
//! library, which can be used to implement networking protocols.
//!
//! # TCP
//!
//! Connecting to an address, via TCP, can be done using [`TcpStream`]'s
//! [`connect`] method, which returns [`TcpStreamNew`]. `TcpStreamNew`
//! implements a future which returns a `TcpStream`.
//!
//! To listen on an address [`TcpListener`] can be used. `TcpListener`'s
//! [`incoming`][incoming_method] method can be used to accept new connections.
//! It return the [`Incoming`] struct, which implements a stream which returns
//! `TcpStream`s.
//!
//! [`TcpStream`]: struct.TcpStream.html
//! [`connect`]: struct.TcpStream.html#method.connect
//! [`TcpStreamNew`]: struct.TcpStreamNew.html
//! [`TcpListener`]: struct.TcpListener.html
//! [incoming_method]: struct.TcpListener.html#method.incoming
//! [`Incoming`]: struct.Incoming.html
//!
//! # UDP
//!
//! The main struct for UDP is the [`UdpSocket`], which represents a UDP socket.
//! Reading and writing to it can be done using futures, which return the
//! [`RecvDgram`] and [`SendDgram`] structs respectively.
//!
//! For convience it's also possible to convert raw datagrams into higher-level
//! frames. This done with [`UdpFramed`], created by calling [`framed`] on a
//! [`UdpSocket`], and using the [`UdpCodec`].
//!
//! [`UdpSocket`]: struct.UdpSocket.html
//! [`RecvDgram`]: struct.RecvDgram.html
//! [`SendDgram`]: struct.SendDgram.html
//! [`UdpFramed`]: struct.UdpFramed.html
//! [`framed`]: struct.UdpSocket.html#method.framed
//! [`UdpCodec`]: trait.UdpCodec.html
mod tcp;
mod udp;

View File

@ -148,6 +148,11 @@ impl TcpListener {
}
/// Test whether this socket is ready to be read or not.
///
/// # Panics
///
/// This function will panic if called outside the context of a future's
/// task.
pub fn poll_read(&self) -> Async<()> {
self.io.poll_read()
}
@ -169,6 +174,15 @@ impl TcpListener {
Incoming { inner: self }
}
/// Gets the value of the `IP_TTL` option for this socket.
///
/// For more information about this option, see [`set_ttl`].
///
/// [`set_ttl`]: #method.set_ttl
pub fn ttl(&self) -> io::Result<u32> {
self.io.get_ref().ttl()
}
/// Sets the value for the `IP_TTL` option on this socket.
///
/// This value sets the time-to-live field that is used in every packet sent
@ -177,13 +191,13 @@ impl TcpListener {
self.io.get_ref().set_ttl(ttl)
}
/// Gets the value of the `IP_TTL` option for this socket.
/// Gets the value of the `IPV6_V6ONLY` option for this socket.
///
/// For more information about this option, see [`set_ttl`][link].
/// For more information about this option, see [`set_only_v6`].
///
/// [link]: #method.set_ttl
pub fn ttl(&self) -> io::Result<u32> {
self.io.get_ref().ttl()
/// [`set_only_v6`]: #method.set_only_v6
pub fn only_v6(&self) -> io::Result<bool> {
self.io.get_ref().only_v6()
}
/// Sets the value for the `IPV6_V6ONLY` option on this socket.
@ -197,15 +211,6 @@ impl TcpListener {
pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
self.io.get_ref().set_only_v6(only_v6)
}
/// Gets the value of the `IPV6_V6ONLY` option for this socket.
///
/// For more information about this option, see [`set_only_v6`][link].
///
/// [link]: #method.set_only_v6
pub fn only_v6(&self) -> io::Result<bool> {
self.io.get_ref().only_v6()
}
}
impl fmt::Debug for TcpListener {
@ -225,10 +230,12 @@ impl Stream for Incoming {
/// An I/O object representing a TCP stream connected to a remote endpoint.
///
/// A TCP stream can either be created by connecting to an endpoint or by
/// accepting a connection from a listener. Inside the stream is access to the
/// raw underlying I/O object as well as streams for the read/write
/// notifications on the stream itself.
/// A TCP stream can either be created by connecting to an endpoint, via the
/// [`connect`] method, or by [accepting] a connection from a [listener].
///
/// [`connect`]: struct.TcpStream.html#method.connect
/// [accepting]: struct.TcpListener.html#method.accept
/// [listener]: struct.TcpListener.html
pub struct TcpStream {
io: PollEvented<mio::net::TcpStream>,
}
@ -252,9 +259,8 @@ impl TcpStream {
///
/// This function will create a new TCP socket and attempt to connect it to
/// the `addr` provided. The returned future will be resolved once the
/// stream has successfully connected. If an error happens during the
/// connection or during the socket creation, that error will be returned to
/// the future instead.
/// stream has successfully connected, or it wil return an error if one
/// occurs.
pub fn connect(addr: &SocketAddr, handle: &Handle) -> TcpStreamNew {
let inner = match mio::net::TcpStream::connect(addr) {
Ok(tcp) => TcpStream::new(tcp, handle),
@ -273,9 +279,10 @@ impl TcpStream {
/// Create a new `TcpStream` from a `net::TcpStream`.
///
/// This function will convert a TCP stream in the standard library to a TCP
/// stream ready to be used with the provided event loop handle. The object
/// returned is associated with the event loop and ready to perform I/O.
/// This function will convert a TCP stream created by the standard library
/// to a TCP stream ready to be used with the provided event loop handle.
/// The stream returned is associated with the event loop and ready to
/// perform I/O.
pub fn from_stream(stream: net::TcpStream, handle: &Handle)
-> io::Result<TcpStream> {
let inner = try!(mio::net::TcpStream::from_stream(stream));
@ -313,22 +320,28 @@ impl TcpStream {
Box::new(state)
}
/// Test whether this socket is ready to be read or not.
/// Test whether this stream is ready to be read or not.
///
/// If the socket is *not* readable then the current task is scheduled to
/// get a notification when the socket does become readable. That is, this
/// is only suitable for calling in a `Future::poll` method and will
/// automatically handle ensuring a retry once the socket is readable again.
/// If the stream is *not* readable then the current task is scheduled to
/// get a notification when the stream does become readable.
///
/// # Panics
///
/// This function will panic if called outside the context of a future's
/// task.
pub fn poll_read(&self) -> Async<()> {
self.io.poll_read()
}
/// Test whether this socket is ready to be written to or not.
/// Test whether this stream is ready to be written or not.
///
/// If the socket is *not* writable then the current task is scheduled to
/// get a notification when the socket does become writable. That is, this
/// is only suitable for calling in a `Future::poll` method and will
/// automatically handle ensuring a retry once the socket is writable again.
/// If the stream is *not* writable then the current task is scheduled to
/// get a notification when the stream does become writable.
///
/// # Panics
///
/// This function will panic if called outside the context of a future's
/// task.
pub fn poll_write(&self) -> Async<()> {
self.io.poll_write()
}
@ -352,6 +365,15 @@ impl TcpStream {
self.io.get_ref().shutdown(how)
}
/// Gets the value of the `TCP_NODELAY` option on this socket.
///
/// For more information about this option, see [`set_nodelay`].
///
/// [`set_nodelay`]: #method.set_nodelay
pub fn nodelay(&self) -> io::Result<bool> {
self.io.get_ref().nodelay()
}
/// Sets the value of the `TCP_NODELAY` option on this socket.
///
/// If set, this option disables the Nagle algorithm. This means that
@ -363,13 +385,13 @@ impl TcpStream {
self.io.get_ref().set_nodelay(nodelay)
}
/// Gets the value of the `TCP_NODELAY` option on this socket.
/// Gets the value of the `SO_RCVBUF` option on this socket.
///
/// For more information about this option, see [`set_nodelay`][link].
/// For more information about this option, see [`set_recv_buffer_size`].
///
/// [link]: #method.set_nodelay
pub fn nodelay(&self) -> io::Result<bool> {
self.io.get_ref().nodelay()
/// [`set_recv_buffer_size`]: #tymethod.set_recv_buffer_size
pub fn recv_buffer_size(&self) -> io::Result<usize> {
self.io.get_ref().recv_buffer_size()
}
/// Sets the value of the `SO_RCVBUF` option on this socket.
@ -380,14 +402,13 @@ impl TcpStream {
self.io.get_ref().set_recv_buffer_size(size)
}
/// Gets the value of the `SO_RCVBUF` option on this socket.
/// Gets the value of the `SO_SNDBUF` option on this socket.
///
/// For more information about this option, see
/// [`set_recv_buffer_size`][link].
/// For more information about this option, see [`set_send_buffer`].
///
/// [link]: #tymethod.set_recv_buffer_size
pub fn recv_buffer_size(&self) -> io::Result<usize> {
self.io.get_ref().recv_buffer_size()
/// [`set_send_buffer`]: #tymethod.set_send_buffer
pub fn send_buffer_size(&self) -> io::Result<usize> {
self.io.get_ref().send_buffer_size()
}
/// Sets the value of the `SO_SNDBUF` option on this socket.
@ -398,13 +419,14 @@ impl TcpStream {
self.io.get_ref().set_send_buffer_size(size)
}
/// Gets the value of the `SO_SNDBUF` option on this socket.
/// Returns whether keepalive messages are enabled on this socket, and if so
/// the duration of time between them.
///
/// For more information about this option, see [`set_send_buffer`][link].
/// For more information about this option, see [`set_keepalive`].
///
/// [link]: #tymethod.set_send_buffer
pub fn send_buffer_size(&self) -> io::Result<usize> {
self.io.get_ref().send_buffer_size()
/// [`set_keepalive`]: #tymethod.set_keepalive
pub fn keepalive(&self) -> io::Result<Option<Duration>> {
self.io.get_ref().keepalive()
}
/// Sets whether keepalive messages are enabled to be sent on this socket.
@ -423,14 +445,13 @@ impl TcpStream {
self.io.get_ref().set_keepalive(keepalive)
}
/// Returns whether keepalive messages are enabled on this socket, and if so
/// the duration of time between them.
/// Gets the value of the `IP_TTL` option for this socket.
///
/// For more information about this option, see [`set_keepalive`][link].
/// For more information about this option, see [`set_ttl`].
///
/// [link]: #tymethod.set_keepalive
pub fn keepalive(&self) -> io::Result<Option<Duration>> {
self.io.get_ref().keepalive()
/// [`set_ttl`]: #tymethod.set_ttl
pub fn ttl(&self) -> io::Result<u32> {
self.io.get_ref().ttl()
}
/// Sets the value for the `IP_TTL` option on this socket.
@ -441,13 +462,13 @@ impl TcpStream {
self.io.get_ref().set_ttl(ttl)
}
/// Gets the value of the `IP_TTL` option for this socket.
/// Gets the value of the `IPV6_V6ONLY` option for this socket.
///
/// For more information about this option, see [`set_ttl`][link].
/// For more information about this option, see [`set_only_v6`].
///
/// [link]: #tymethod.set_ttl
pub fn ttl(&self) -> io::Result<u32> {
self.io.get_ref().ttl()
/// [`set_only_v6`]: #tymethod.set_only_v6
pub fn only_v6(&self) -> io::Result<bool> {
self.io.get_ref().only_v6()
}
/// Sets the value for the `IPV6_V6ONLY` option on this socket.
@ -462,24 +483,30 @@ impl TcpStream {
self.io.get_ref().set_only_v6(only_v6)
}
/// Gets the value of the `IPV6_V6ONLY` option for this socket.
/// Reads the linger duration for this socket by getting the `SO_LINGER`
/// option.
///
/// For more information about this option, see [`set_only_v6`][link].
/// For more information about this option, see [`set_linger`].
///
/// [link]: #tymethod.set_only_v6
pub fn only_v6(&self) -> io::Result<bool> {
self.io.get_ref().only_v6()
}
/// Sets the linger duration of this socket by setting the SO_LINGER option
pub fn set_linger(&self, dur: Option<Duration>) -> io::Result<()> {
self.io.get_ref().set_linger(dur)
}
/// reads the linger duration for this socket by getting the SO_LINGER option
/// [`set_linger`]: #tymethod.set_linger
pub fn linger(&self) -> io::Result<Option<Duration>> {
self.io.get_ref().linger()
}
/// Sets the linger duration of this socket by setting the `SO_LINGER`
/// option.
///
/// This option controls the action taken when a stream has unsent messages
/// and the stream is closed. If `SO_LINGER` is set, the system
/// shall block the process until it can transmit the data or until the
/// time expires.
///
/// If `SO_LINGER` is not specified, and the stream is closed, the system
/// handles the call in a way that allows the process to continue as quickly
/// as possible.
pub fn set_linger(&self, dur: Option<Duration>) -> io::Result<()> {
self.io.get_ref().set_linger(dur)
}
}
impl Read for TcpStream {

View File

@ -5,7 +5,7 @@ use futures::{Async, Poll, Stream, Sink, StartSend, AsyncSink};
use net::UdpSocket;
/// Encoding of frames via buffers.
/// Encoding of datagrams into frames via buffers.
///
/// This trait is used when constructing an instance of `UdpFramed` and provides
/// the `In` and `Out` types which are decoded and encoded from the socket,
@ -18,7 +18,7 @@ use net::UdpSocket;
/// The trait itself is implemented on a type that can track state for decoding
/// or encoding, which is particularly useful for streaming parsers. In many
/// cases, though, this type will simply be a unit struct (e.g. `struct
/// HttpCodec`).
/// MyCodec`).
pub trait UdpCodec {
/// The type of decoded frames.
type In;
@ -140,9 +140,11 @@ pub fn new<C: UdpCodec>(socket: UdpSocket, codec: C) -> UdpFramed<C> {
impl<C> UdpFramed<C> {
/// Returns a reference to the underlying I/O stream wrapped by `Framed`.
///
/// Note that care should be taken to not tamper with the underlying stream
/// of data coming in as it may corrupt the stream of frames otherwise being
/// worked with.
/// # Note
///
/// Care should be taken to not tamper with the underlying stream of data
/// coming in as it may corrupt the stream of frames otherwise being worked
/// with.
pub fn get_ref(&self) -> &UdpSocket {
&self.socket
}
@ -150,18 +152,16 @@ impl<C> UdpFramed<C> {
/// Returns a mutable reference to the underlying I/O stream wrapped by
/// `Framed`.
///
/// Note that care should be taken to not tamper with the underlying stream
/// of data coming in as it may corrupt the stream of frames otherwise being
/// worked with.
/// # Note
///
/// Care should be taken to not tamper with the underlying stream of data
/// coming in as it may corrupt the stream of frames otherwise being worked
/// with.
pub fn get_mut(&mut self) -> &mut UdpSocket {
&mut self.socket
}
/// Consumes the `Framed`, returning its underlying I/O stream.
///
/// Note that care should be taken to not tamper with the underlying stream
/// of data coming in as it may corrupt the stream of frames otherwise being
/// worked with.
pub fn into_inner(self) -> UdpSocket {
self.socket
}

View File

@ -16,10 +16,8 @@ mod frame;
pub use self::frame::{UdpFramed, UdpCodec};
impl UdpSocket {
/// Create a new UDP socket bound to the specified address.
///
/// This function will create a new UDP socket and attempt to bind it to the
/// `addr` provided. If the result is `Ok`, the socket has successfully bound.
/// This function will create a new UDP socket and attempt to bind it to
/// the `addr` provided.
pub fn bind(addr: &SocketAddr, handle: &Handle) -> io::Result<UdpSocket> {
let udp = try!(mio::net::UdpSocket::bind(addr));
UdpSocket::new(udp, handle)
@ -32,8 +30,8 @@ impl UdpSocket {
/// Creates a new `UdpSocket` from the previously bound socket provided.
///
/// The socket given will be registered with the event loop that `handle` is
/// associated with. This function requires that `socket` has previously
/// The socket given will be registered with the event loop that `handle`
/// is associated with. This function requires that `socket` has previously
/// been bound to an address to work correctly.
///
/// This can be used in conjunction with net2's `UdpBuilder` interface to
@ -68,19 +66,25 @@ impl UdpSocket {
frame::new(self, codec)
}
/// Returns the local address that this stream is bound to.
/// Returns the local address that this socket is bound to.
pub fn local_addr(&self) -> io::Result<SocketAddr> {
self.io.get_ref().local_addr()
}
/// Connects the UDP socket setting the default destination for send() and
/// limiting packets that are read via recv from the address specified in addr.
/// limiting packets that are read via recv from the address specified in
/// `addr`.
pub fn connect(&self, addr: &SocketAddr) -> io::Result<()> {
self.io.get_ref().connect(*addr)
}
/// Sends data on the socket to the address previously bound via connect().
/// On success, returns the number of bytes written.
///
/// # Panics
///
/// This function will panic if called outside the context of a future's
/// task.
pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
if let Async::NotReady = self.io.poll_write() {
return Err(io::ErrorKind::WouldBlock.into())
@ -98,6 +102,11 @@ impl UdpSocket {
/// Receives data from the socket previously bound with connect().
/// On success, returns the number of bytes read.
///
/// # Panics
///
/// This function will panic if called outside the context of a future's
/// task.
pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
if let Async::NotReady = self.io.poll_read() {
return Err(io::ErrorKind::WouldBlock.into())
@ -116,9 +125,12 @@ impl UdpSocket {
/// Test whether this socket is ready to be read or not.
///
/// If the socket is *not* readable then the current task is scheduled to
/// get a notification when the socket does become readable. That is, this
/// is only suitable for calling in a `Future::poll` method and will
/// automatically handle ensuring a retry once the socket is readable again.
/// get a notification when the socket does become readable.
///
/// # Panics
///
/// This function will panic if called outside the context of a future's
/// task.
pub fn poll_read(&self) -> Async<()> {
self.io.poll_read()
}
@ -126,9 +138,12 @@ impl UdpSocket {
/// Test whether this socket is ready to be written to or not.
///
/// If the socket is *not* writable then the current task is scheduled to
/// get a notification when the socket does become writable. That is, this
/// is only suitable for calling in a `Future::poll` method and will
/// automatically handle ensuring a retry once the socket is writable again.
/// get a notification when the socket does become writable.
///
/// # Panics
///
/// This function will panic if called outside the context of a future's
/// task.
pub fn poll_write(&self) -> Async<()> {
self.io.poll_write()
}
@ -136,8 +151,10 @@ impl UdpSocket {
/// Sends data on the socket to the given address. On success, returns the
/// number of bytes written.
///
/// Address type can be any implementer of `ToSocketAddrs` trait. See its
/// documentation for concrete examples.
/// # Panics
///
/// This function will panic if called outside the context of a future's
/// task.
pub fn send_to(&self, buf: &[u8], target: &SocketAddr) -> io::Result<usize> {
if let Async::NotReady = self.io.poll_write() {
return Err(io::ErrorKind::WouldBlock.into())
@ -157,7 +174,7 @@ impl UdpSocket {
/// `buf` provided as a datagram to this socket.
///
/// The returned future will return after data has been written to the
/// outbound socket. The future will resolve to the stream as well as the
/// outbound socket. The future will resolve to the stream as well as the
/// buffer (for reuse if needed).
///
/// Any error which happens during writing will cause both the stream and
@ -166,8 +183,7 @@ impl UdpSocket {
///
/// The `buf` parameter here only requires the `AsRef<[u8]>` trait, which
/// should be broadly applicable to accepting data which can be converted
/// to a slice. The `Window` struct is also available in this crate to
/// provide a different window into a slice if necessary.
/// to a slice.
pub fn send_dgram<T>(self, buf: T, addr: SocketAddr) -> SendDgram<T>
where T: AsRef<[u8]>,
{
@ -176,6 +192,11 @@ impl UdpSocket {
/// Receives data from the socket. On success, returns the number of bytes
/// read and the address from whence the data came.
///
/// # Panics
///
/// This function will panic if called outside the context of a future's
/// task.
pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
if let Async::NotReady = self.io.poll_read() {
return Err(io::ErrorKind::WouldBlock.into())
@ -199,12 +220,11 @@ impl UdpSocket {
/// amount of data read, and the address the data was received from.
///
/// An error during reading will cause the socket and buffer to get
/// destroyed and the socket will be returned.
/// destroyed.
///
/// The `buf` parameter here only requires the `AsMut<[u8]>` trait, which
/// should be broadly applicable to accepting data which can be converted
/// to a slice. The `Window` struct is also available in this crate to
/// provide a different window into a slice if necessary.
/// to a slice.
pub fn recv_dgram<T>(self, buf: T) -> RecvDgram<T>
where T: AsMut<[u8]>,
{
@ -213,10 +233,9 @@ impl UdpSocket {
/// Gets the value of the `SO_BROADCAST` option for this socket.
///
/// For more information about this option, see
/// [`set_broadcast`][link].
/// For more information about this option, see [`set_broadcast`].
///
/// [link]: #method.set_broadcast
/// [`set_broadcast`]: #method.set_broadcast
pub fn broadcast(&self) -> io::Result<bool> {
self.io.get_ref().broadcast()
}
@ -231,10 +250,9 @@ impl UdpSocket {
/// Gets the value of the `IP_MULTICAST_LOOP` option for this socket.
///
/// For more information about this option, see
/// [`set_multicast_loop_v4`][link].
/// For more information about this option, see [`set_multicast_loop_v4`].
///
/// [link]: #method.set_multicast_loop_v4
/// [`set_multicast_loop_v4`]: #method.set_multicast_loop_v4
pub fn multicast_loop_v4(&self) -> io::Result<bool> {
self.io.get_ref().multicast_loop_v4()
}
@ -242,17 +260,19 @@ impl UdpSocket {
/// Sets the value of the `IP_MULTICAST_LOOP` option for this socket.
///
/// If enabled, multicast packets will be looped back to the local socket.
/// Note that this may not have any affect on IPv6 sockets.
///
/// # Note
///
/// This may not have any affect on IPv6 sockets.
pub fn set_multicast_loop_v4(&self, on: bool) -> io::Result<()> {
self.io.get_ref().set_multicast_loop_v4(on)
}
/// Gets the value of the `IP_MULTICAST_TTL` option for this socket.
///
/// For more information about this option, see
/// [`set_multicast_ttl_v4`][link].
/// For more information about this option, see [`set_multicast_ttl_v4`].
///
/// [link]: #method.set_multicast_ttl_v4
/// [`set_multicast_ttl_v4`]: #method.set_multicast_ttl_v4
pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
self.io.get_ref().multicast_ttl_v4()
}
@ -263,17 +283,18 @@ impl UdpSocket {
/// this socket. The default value is 1 which means that multicast packets
/// don't leave the local network unless explicitly requested.
///
/// Note that this may not have any affect on IPv6 sockets.
/// # Note
///
/// This may not have any affect on IPv6 sockets.
pub fn set_multicast_ttl_v4(&self, ttl: u32) -> io::Result<()> {
self.io.get_ref().set_multicast_ttl_v4(ttl)
}
/// Gets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
///
/// For more information about this option, see
/// [`set_multicast_loop_v6`][link].
/// For more information about this option, see [`set_multicast_loop_v6`].
///
/// [link]: #method.set_multicast_loop_v6
/// [`set_multicast_loop_v6`]: #method.set_multicast_loop_v6
pub fn multicast_loop_v6(&self) -> io::Result<bool> {
self.io.get_ref().multicast_loop_v6()
}
@ -281,16 +302,19 @@ impl UdpSocket {
/// Sets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
///
/// Controls whether this socket sees the multicast packets it sends itself.
/// Note that this may not have any affect on IPv4 sockets.
///
/// # Note
///
/// This may not have any affect on IPv4 sockets.
pub fn set_multicast_loop_v6(&self, on: bool) -> io::Result<()> {
self.io.get_ref().set_multicast_loop_v6(on)
}
/// Gets the value of the `IP_TTL` option for this socket.
///
/// For more information about this option, see [`set_ttl`][link].
/// For more information about this option, see [`set_ttl`].
///
/// [link]: #method.set_ttl
/// [`set_ttl`]: #method.set_ttl
pub fn ttl(&self) -> io::Result<u32> {
self.io.get_ref().ttl()
}
@ -329,10 +353,9 @@ impl UdpSocket {
/// Executes an operation of the `IP_DROP_MEMBERSHIP` type.
///
/// For more information about this option, see
/// [`join_multicast_v4`][link].
/// For more information about this option, see [`join_multicast_v4`].
///
/// [link]: #method.join_multicast_v4
/// [`join_multicast_v4`]: #method.join_multicast_v4
pub fn leave_multicast_v4(&self,
multiaddr: &Ipv4Addr,
interface: &Ipv4Addr) -> io::Result<()> {
@ -341,10 +364,9 @@ impl UdpSocket {
/// Executes an operation of the `IPV6_DROP_MEMBERSHIP` type.
///
/// For more information about this option, see
/// [`join_multicast_v6`][link].
/// For more information about this option, see [`join_multicast_v6`].
///
/// [link]: #method.join_multicast_v6
/// [`join_multicast_v6`]: #method.join_multicast_v6
pub fn leave_multicast_v6(&self,
multiaddr: &Ipv6Addr,
interface: u32) -> io::Result<()> {
@ -365,9 +387,9 @@ impl UdpSocket {
/// Gets the value of the `IPV6_V6ONLY` option for this socket.
///
/// For more information about this option, see [`set_only_v6`][link].
/// For more information about this option, see [`set_only_v6`].
///
/// [link]: #method.set_only_v6
/// [`set_only_v6`]: #method.set_only_v6
pub fn only_v6(&self) -> io::Result<bool> {
self.io.get_ref().only_v6()
}

View File

@ -12,8 +12,8 @@ pub struct IoToken {
}
impl IoToken {
/// Add a new source to an event loop, returning a future which will resolve
/// to the token that can be used to identify this source.
/// Add a new source to an event loop, returning a token that can be used to
/// identify this source.
///
/// When a new I/O object is created it needs to be communicated to the
/// event loop to ensure that it's registered and ready to receive
@ -40,7 +40,7 @@ impl IoToken {
}
}
/// Returns a reference to the remote handle
/// Returns a reference to the remote handle.
pub fn remote(&self) -> &Remote {
&self.handle
}
@ -137,8 +137,8 @@ impl IoToken {
/// deallocating all internal resources assigned to the given token.
///
/// This method should be called whenever a source of events is being
/// destroyed. This will ensure that the event loop can reuse `tok` for
/// another I/O object if necessary and also remove it from any poll
/// destroyed. This will ensure that the event loop can reuse the `token`
/// for another I/O object if necessary and also remove it from any poll
/// notifications and callbacks.
///
/// Note that wake callbacks may still be invoked after this method is

View File

@ -1,8 +1,24 @@
//! The core reactor driving all I/O
//! The core reactor driving all I/O.
//!
//! This module contains the `Core` type which is the reactor for all I/O
//! happening in `tokio-core`. This reactor (or event loop) is used to drive I/O
//! resources.
//! This module contains the [`Core`] reactor type which is the event loop for
//! all I/O happening in `tokio`. This core reactor (or event loop) is used to
//! drive I/O resources.
//!
//! The [`Handle`] and [`Remote`] structs are refences to the event loop,
//! created by the [`handle`][handle_method] and [`remote`][remote_method]
//! respectively, and are used to construct I/O objects. `Remote` is sendable,
//! while `Handle` is not.
//!
//! Lastly [`PollEvented`] can be used to construct I/O objects that interact
//! with the event loop, e.g. [`TcpStream`] in the net module.
//!
//! [`Core`]: struct.Core.html
//! [`Handle`]: struct.Handle.html
//! [`Remote`]: struct.Remote.html
//! [handle_method]: struct.Core.html#method.handle
//! [remote_method]: struct.Core.html#method.remote
//! [`PollEvented`]: struct.PollEvented.html
//! [`TcpStream`]: ../net/struct.TcpStream.html
use std::fmt;
use std::io::{self, ErrorKind};
@ -25,7 +41,7 @@ pub use self::poll_evented::PollEvented;
/// Global counter used to assign unique IDs to reactor instances.
static NEXT_LOOP_ID: AtomicUsize = ATOMIC_USIZE_INIT;
/// An event loop.
/// The core reactor, or event loop.
///
/// The event loop is the main source of blocking in an application which drives
/// all other I/O events and notifications happening. Each event loop can have
@ -56,19 +72,27 @@ struct Inner {
io_dispatch: RwLock<Slab<ScheduledIo>>,
}
/// Handle to an event loop, used to construct I/O objects, send messages, and
/// otherwise interact indirectly with the event loop itself.
/// A remote handle to an event loop, for more information see [`Handle`].
///
/// Handles can be cloned, and when cloned they will still refer to the
/// This handle can be cloned, and when cloned they will still refer to the
/// same underlying event loop.
///
/// [`Handle`]: struct.Handle.html
#[derive(Clone)]
pub struct Remote {
id: usize,
inner: Weak<Inner>,
}
/// A non-sendable handle to an event loop, useful for manufacturing instances
/// of `LoopData`.
/// A handle to an event loop, used to construct I/O objects, send messages, and
/// otherwise interact indirectly with the event loop itself.
///
/// Handles can be cloned, and when cloned they will still refer to the
/// same underlying event loop.
///
/// Handles are non-sendable, see [`Remote`] for a sendable reference.
///
/// [`Remote`]: struct.Remote.html
#[derive(Clone)]
pub struct Handle {
remote: Remote,
@ -316,8 +340,8 @@ impl Remote {
/// the I/O loop itself. The future returned by the closure will be
/// scheduled on the event loop and run to completion.
///
/// Note that while the closure, `F`, requires the `Send` bound as it might
/// cross threads, the future `R` does not.
/// Note that the closure, `F`, requires the `Send` bound as it might cross
/// threads.
///
/// # Panics
///

View File

@ -80,9 +80,6 @@ impl<E: fmt::Debug> fmt::Debug for PollEvented<E> {
impl<E: Evented> PollEvented<E> {
/// Creates a new readiness stream associated with the provided
/// `loop_handle` and for the given `source`.
///
/// This method returns a future which will resolve to the readiness stream
/// when it's ready.
pub fn new(io: E, handle: &Handle) -> io::Result<PollEvented<E>> {
let token = IoToken::new(&io, handle)?;
@ -118,11 +115,11 @@ impl<E: Evented> PollEvented<E> {
impl<E> PollEvented<E> {
/// Tests to see if this source is ready to be read from or not.
///
/// If this stream is not ready for a read then `NotReady` will be returned
/// and the current task will be scheduled to receive a notification when
/// the stream is readable again. In other words, this method is only safe
/// to call from within the context of a future's task, typically done in a
/// `Future::poll` method.
/// If this stream is not ready for a read then `Async::NotReady` will be
/// returned and the current task will be scheduled to receive a
/// notification when the stream is readable again. In other words, this
/// method is only safe to call from within the context of a future's task,
/// typically done in a `Future::poll` method.
///
/// This is mostly equivalent to `self.poll_ready(Ready::readable())`.
///
@ -137,7 +134,7 @@ impl<E> PollEvented<E> {
/// Tests to see if this source is ready to be written to or not.
///
/// If this stream is not ready for a write then `NotReady` will be returned
/// If this stream is not ready for a write then `Async::NotReady` will be returned
/// and the current task will be scheduled to receive a notification when
/// the stream is writable again. In other words, this method is only safe
/// to call from within the context of a future's task, typically done in a