Rename reactor -> driver, prep for lib/reactivity
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
//! Portable async networking API.
|
||||
//!
|
||||
//! The public surface follows the general shape of `std::net`, but uses async methods for socket
|
||||
//! operations that would otherwise block the caller.
|
||||
|
||||
use std::future::Future;
|
||||
use std::io;
|
||||
@@ -40,6 +43,10 @@ type PendingRead = Pin<Box<dyn Future<Output = io::Result<Vec<u8>>> + 'static>>;
|
||||
type PendingWrite = Pin<Box<dyn Future<Output = io::Result<usize>> + 'static>>;
|
||||
type PendingShutdown = Pin<Box<dyn Future<Output = io::Result<()>> + 'static>>;
|
||||
|
||||
/// Async TCP stream.
|
||||
///
|
||||
/// This type also implements Hyper's runtime I/O traits, allowing it to be used directly as an
|
||||
/// HTTP transport.
|
||||
pub struct TcpStream {
|
||||
inner: Arc<TcpStreamInner>,
|
||||
pending_read: Option<PendingRead>,
|
||||
@@ -48,16 +55,19 @@ pub struct TcpStream {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Async TCP listening socket.
|
||||
pub struct TcpListener {
|
||||
inner: Arc<TcpListenerInner>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Async UDP socket.
|
||||
pub struct UdpSocket {
|
||||
inner: Arc<UdpSocketInner>,
|
||||
}
|
||||
|
||||
impl TcpStream {
|
||||
/// Connects to the first resolved address that succeeds.
|
||||
pub async fn connect<A>(addr: A) -> io::Result<Self>
|
||||
where
|
||||
A: ToSocketAddrs + Send + 'static,
|
||||
@@ -79,6 +89,7 @@ impl TcpStream {
|
||||
}))
|
||||
}
|
||||
|
||||
/// Connects to `addr`, failing if the deadline elapses first.
|
||||
pub async fn connect_timeout(addr: &SocketAddr, timeout: Duration) -> io::Result<Self> {
|
||||
validate_timeout(timeout)?;
|
||||
crate::sys::linux::net::connect_stream_timeout(*addr, timeout)
|
||||
@@ -86,6 +97,7 @@ impl TcpStream {
|
||||
.map(Self::from_owned_fd)
|
||||
}
|
||||
|
||||
/// Reads bytes from the stream.
|
||||
pub async fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
let data = match self.read_timeout_value() {
|
||||
Some(timeout) => {
|
||||
@@ -105,6 +117,7 @@ impl TcpStream {
|
||||
Ok(read)
|
||||
}
|
||||
|
||||
/// Reads exactly `buf.len()` bytes from the stream.
|
||||
pub async fn read_exact(&mut self, mut buf: &mut [u8]) -> io::Result<()> {
|
||||
while !buf.is_empty() {
|
||||
let read = self.read(buf).await?;
|
||||
@@ -119,6 +132,7 @@ impl TcpStream {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Writes bytes to the stream.
|
||||
pub async fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
match self.write_timeout_value() {
|
||||
Some(timeout) => {
|
||||
@@ -135,6 +149,7 @@ impl TcpStream {
|
||||
}
|
||||
}
|
||||
|
||||
/// Writes the entire buffer to the stream.
|
||||
pub async fn write_all(&mut self, mut buf: &[u8]) -> io::Result<()> {
|
||||
while !buf.is_empty() {
|
||||
let written = self.write(buf).await?;
|
||||
@@ -149,6 +164,7 @@ impl TcpStream {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Shuts down the read, write, or both halves of the connection.
|
||||
pub async fn shutdown(&self, how: Shutdown) -> io::Result<()> {
|
||||
crate::sys::linux::net::shutdown(NetOp::Shutdown {
|
||||
fd: self.raw_fd(),
|
||||
@@ -157,50 +173,65 @@ impl TcpStream {
|
||||
.await
|
||||
}
|
||||
|
||||
/// Duplicates the underlying stream socket.
|
||||
pub async fn try_clone(&self) -> io::Result<Self> {
|
||||
crate::sys::linux::net::duplicate(self.raw_fd())
|
||||
.await
|
||||
.map(Self::from_owned_fd)
|
||||
}
|
||||
|
||||
/// Returns the local socket address of this stream.
|
||||
pub fn local_addr(&self) -> io::Result<SocketAddr> {
|
||||
crate::sys::linux::net::local_addr(self.raw_fd())
|
||||
}
|
||||
|
||||
/// Returns the remote peer address of this stream.
|
||||
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||
crate::sys::linux::net::peer_addr(self.raw_fd())
|
||||
}
|
||||
|
||||
/// Reads the current `TCP_NODELAY` setting.
|
||||
pub fn nodelay(&self) -> io::Result<bool> {
|
||||
crate::sys::linux::net::nodelay(self.raw_fd())
|
||||
}
|
||||
|
||||
/// Enables or disables `TCP_NODELAY`.
|
||||
pub fn set_nodelay(&self, enabled: bool) -> io::Result<()> {
|
||||
crate::sys::linux::net::set_nodelay(self.raw_fd(), enabled)
|
||||
}
|
||||
|
||||
/// Reads the socket's IP time-to-live value.
|
||||
pub fn ttl(&self) -> io::Result<u32> {
|
||||
crate::sys::linux::net::ttl(self.raw_fd())
|
||||
}
|
||||
|
||||
/// Sets the socket's IP time-to-live value.
|
||||
pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
|
||||
crate::sys::linux::net::set_ttl(self.raw_fd(), ttl)
|
||||
}
|
||||
|
||||
/// Returns the read timeout used by async read operations on this handle.
|
||||
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
|
||||
Ok(self.read_timeout_value())
|
||||
}
|
||||
|
||||
/// Sets the read timeout used by async read operations on this handle.
|
||||
///
|
||||
/// Passing `Some(Duration::ZERO)` is rejected.
|
||||
pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
|
||||
validate_optional_timeout(timeout)?;
|
||||
self.inner.timeouts.lock().unwrap().read = timeout;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns the write timeout used by async write operations on this handle.
|
||||
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
|
||||
Ok(self.write_timeout_value())
|
||||
}
|
||||
|
||||
/// Sets the write timeout used by async write operations on this handle.
|
||||
///
|
||||
/// Passing `Some(Duration::ZERO)` is rejected.
|
||||
pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
|
||||
validate_optional_timeout(timeout)?;
|
||||
self.inner.timeouts.lock().unwrap().write = timeout;
|
||||
@@ -233,6 +264,7 @@ impl TcpStream {
|
||||
}
|
||||
|
||||
impl TcpListener {
|
||||
/// Binds a TCP listener to the first resolved address that succeeds.
|
||||
pub async fn bind<A>(addr: A) -> io::Result<Self>
|
||||
where
|
||||
A: ToSocketAddrs + Send + 'static,
|
||||
@@ -254,6 +286,7 @@ impl TcpListener {
|
||||
}))
|
||||
}
|
||||
|
||||
/// Accepts an incoming connection.
|
||||
pub async fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
|
||||
let accepted = crate::sys::linux::net::accept(NetOp::Accept { fd: self.raw_fd() }).await?;
|
||||
|
||||
@@ -261,14 +294,17 @@ impl TcpListener {
|
||||
Ok((stream, accepted.peer_addr))
|
||||
}
|
||||
|
||||
/// Returns the local socket address of this listener.
|
||||
pub fn local_addr(&self) -> io::Result<SocketAddr> {
|
||||
crate::sys::linux::net::local_addr(self.raw_fd())
|
||||
}
|
||||
|
||||
/// Reads the listener socket's IP time-to-live value.
|
||||
pub fn ttl(&self) -> io::Result<u32> {
|
||||
crate::sys::linux::net::ttl(self.raw_fd())
|
||||
}
|
||||
|
||||
/// Sets the listener socket's IP time-to-live value.
|
||||
pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
|
||||
crate::sys::linux::net::set_ttl(self.raw_fd(), ttl)
|
||||
}
|
||||
@@ -285,6 +321,7 @@ impl TcpListener {
|
||||
}
|
||||
|
||||
impl UdpSocket {
|
||||
/// Binds a UDP socket to the first resolved address that succeeds.
|
||||
pub async fn bind<A>(addr: A) -> io::Result<Self>
|
||||
where
|
||||
A: ToSocketAddrs + Send + 'static,
|
||||
@@ -306,6 +343,10 @@ impl UdpSocket {
|
||||
}))
|
||||
}
|
||||
|
||||
/// Connects the socket to a default peer.
|
||||
///
|
||||
/// Once connected, [`send`](Self::send), [`recv`](Self::recv), and [`peer_addr`](Self::peer_addr)
|
||||
/// operate relative to that peer.
|
||||
pub async fn connect<A>(&self, addr: A) -> io::Result<()>
|
||||
where
|
||||
A: ToSocketAddrs + Send + 'static,
|
||||
@@ -332,6 +373,7 @@ impl UdpSocket {
|
||||
}))
|
||||
}
|
||||
|
||||
/// Sends a datagram to the connected peer.
|
||||
pub async fn send(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
match self.write_timeout_value() {
|
||||
Some(timeout) => {
|
||||
@@ -348,6 +390,7 @@ impl UdpSocket {
|
||||
}
|
||||
}
|
||||
|
||||
/// Receives a datagram from the connected peer.
|
||||
pub async fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
let data = match self.read_timeout_value() {
|
||||
Some(timeout) => {
|
||||
@@ -367,6 +410,7 @@ impl UdpSocket {
|
||||
Ok(read)
|
||||
}
|
||||
|
||||
/// Peeks at the next datagram from the connected peer without consuming it.
|
||||
pub async fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
let data = match self.read_timeout_value() {
|
||||
Some(timeout) => {
|
||||
@@ -392,6 +436,7 @@ impl UdpSocket {
|
||||
Ok(read)
|
||||
}
|
||||
|
||||
/// Sends a datagram to `addr`.
|
||||
pub async fn send_to<A>(&self, buf: &[u8], addr: A) -> io::Result<usize>
|
||||
where
|
||||
A: ToSocketAddrs + Send + 'static,
|
||||
@@ -435,6 +480,7 @@ impl UdpSocket {
|
||||
}))
|
||||
}
|
||||
|
||||
/// Receives a datagram and returns the sender address.
|
||||
pub async fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
||||
let datagram = match self.read_timeout_value() {
|
||||
Some(timeout) => {
|
||||
@@ -455,6 +501,7 @@ impl UdpSocket {
|
||||
Ok((read, datagram.peer_addr))
|
||||
}
|
||||
|
||||
/// Peeks at the next datagram and returns the sender address without consuming it.
|
||||
pub async fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
||||
let datagram = match self.read_timeout_value() {
|
||||
Some(timeout) => {
|
||||
@@ -480,50 +527,65 @@ impl UdpSocket {
|
||||
Ok((read, datagram.peer_addr))
|
||||
}
|
||||
|
||||
/// Duplicates the underlying UDP socket.
|
||||
pub async fn try_clone(&self) -> io::Result<Self> {
|
||||
crate::sys::linux::net::duplicate(self.raw_fd())
|
||||
.await
|
||||
.map(Self::from_owned_fd)
|
||||
}
|
||||
|
||||
/// Returns the local socket address of this socket.
|
||||
pub fn local_addr(&self) -> io::Result<SocketAddr> {
|
||||
crate::sys::linux::net::local_addr(self.raw_fd())
|
||||
}
|
||||
|
||||
/// Returns the connected peer address, if the socket has been connected.
|
||||
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||
crate::sys::linux::net::peer_addr(self.raw_fd())
|
||||
}
|
||||
|
||||
/// Reads the `SO_BROADCAST` setting.
|
||||
pub fn broadcast(&self) -> io::Result<bool> {
|
||||
crate::sys::linux::net::broadcast(self.raw_fd())
|
||||
}
|
||||
|
||||
/// Enables or disables `SO_BROADCAST`.
|
||||
pub fn set_broadcast(&self, enabled: bool) -> io::Result<()> {
|
||||
crate::sys::linux::net::set_broadcast(self.raw_fd(), enabled)
|
||||
}
|
||||
|
||||
/// Reads the socket's IP time-to-live value.
|
||||
pub fn ttl(&self) -> io::Result<u32> {
|
||||
crate::sys::linux::net::ttl(self.raw_fd())
|
||||
}
|
||||
|
||||
/// Sets the socket's IP time-to-live value.
|
||||
pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
|
||||
crate::sys::linux::net::set_ttl(self.raw_fd(), ttl)
|
||||
}
|
||||
|
||||
/// Returns the read timeout used by async receive operations on this handle.
|
||||
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
|
||||
Ok(self.read_timeout_value())
|
||||
}
|
||||
|
||||
/// Sets the read timeout used by async receive operations on this handle.
|
||||
///
|
||||
/// Passing `Some(Duration::ZERO)` is rejected.
|
||||
pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
|
||||
validate_optional_timeout(timeout)?;
|
||||
self.inner.timeouts.lock().unwrap().read = timeout;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns the write timeout used by async send operations on this handle.
|
||||
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
|
||||
Ok(self.write_timeout_value())
|
||||
}
|
||||
|
||||
/// Sets the write timeout used by async send operations on this handle.
|
||||
///
|
||||
/// Passing `Some(Duration::ZERO)` is rejected.
|
||||
pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
|
||||
validate_optional_timeout(timeout)?;
|
||||
self.inner.timeouts.lock().unwrap().write = timeout;
|
||||
|
||||
Reference in New Issue
Block a user