Struct Async

Source
pub struct Async<T> { /* private fields */ }
Expand description

Async adapter for I/O types

This type puts the I/O object into non-blocking mode, registers it on the reactor, and provides an async interface for it, including the AsyncRead and AsyncWrite traits.

§Supported types

Async supports any type that implements AsFd or AsSocket. This includes all standard networking types. However, Async should not be used with types like File or Stdin, because they don’t work well in non-blocking mode.

§Concurrency

Most operations on Async take &self, so tasks can access it concurrently. However, only one task can read at a time, and only one task can write at a time. It is fine to have one task reading while another one writes, but it is not fine to have multiple tasks reading or multiple tasks writing. Doing so will lead to wakers being lost, which can prevent tasks from waking up properly.

§Examples

use std::net::TcpStream;
use local_runtime::io::Async;
use futures_lite::AsyncWriteExt;

let mut stream = Async::<TcpStream>::connect(([127, 0, 0, 1], 8000)).await?;
stream.write_all(b"hello").await?;

Implementations§

Source§

impl<T: AsFd> Async<T>

Source

pub fn without_nonblocking(inner: T) -> Result<Self>

Create a new async adapter around the I/O object without setting it to non-blocking mode.

This will register the I/O object onto the reactor.

The caller must ensure the I/O object has already been set to non-blocking mode. Otherwise it may block the async runtime, preventing other futures from executing on the same thread.

§Error

If there is currently another Async constructed on the same I/O object on the current thread, this function will return an error.

Source

pub fn new(inner: T) -> Result<Self>

Create a new async adapter around the I/O object.

This will set the I/O object to non-blocking mode and register it onto the reactor.

§Error

If there is currently another Async constructed on the same I/O object on the current thread, this function will return an error.

Source§

impl<T> Async<T>

Source

pub fn get_ref(&self) -> &T

Get reference to inner I/O handle

Source

pub fn into_inner(self) -> T

Deregisters the I/O handle from the reactor and return it

Source

pub unsafe fn poll_read_with<'a, P, F>( &'a self, cx: &mut Context<'_>, f: F, ) -> Poll<Result<P>>
where F: FnOnce(&'a T) -> Result<P>,

Perform a single non-blocking read operation

The underlying I/O object is read by the f closure once. If the result is io::ErrorKind::WouldBlock, then this method returns Poll::Pending and tells the reactor to notify the context cx when the I/O object becomes readable.

The closure should not perform multiple I/O operations, such as calling Write::write_all. This is because the closure is restarted for each poll, so the first I/O operation will be repeated and the subsequent operations won’t be completed.

§Safety

The closure must not drop the underlying I/O object.

§Example

The non-blocking read operation can be converted into a future by wrapping this method in poll_fn.

use std::net::TcpListener;
use std::future::poll_fn;
use local_runtime::io::Async;

let mut listener = Async::<TcpListener>::bind(([127, 0, 0, 1], 0))?;
// Accept connections asynchronously
let (stream, addr) = poll_fn(|cx| unsafe { listener.poll_read_with(cx, |l| l.accept()) }).await?;
Source

pub unsafe fn poll_read_with_mut<'a, P, F>( &'a mut self, cx: &mut Context<'_>, f: F, ) -> Poll<Result<P>>
where F: FnOnce(&'a mut T) -> Result<P>,

Same as Self::poll_read_with, but takes a mutable reference in the closure

§Safety

The closure must not drop the underlying I/O object.

Source

pub unsafe fn poll_write_with<'a, P, F>( &'a self, cx: &mut Context<'_>, f: F, ) -> Poll<Result<P>>
where F: FnOnce(&'a T) -> Result<P>,

Perform a single non-blocking write operation

The underlying I/O object is write by the f closure once. If the result is io::ErrorKind::WouldBlock, then this method returns Poll::Pending and tells the reactor to notify the context cx when the I/O object becomes writable.

The closure should not perform multiple I/O operations, such as calling Write::write_all. This is because the closure is restarted for each poll, so the first I/O operation will be repeated and the subsequent operations won’t be completed.

§Safety

The closure must not drop the underlying I/O object.

§Example

The non-blocking write operation can be converted into a future by wrapping this method in poll_fn.

use std::net::TcpStream;
use std::future::poll_fn;
use std::io::Write;
use local_runtime::io::Async;

let mut stream = Async::<TcpStream>::connect(([127, 0, 0, 1], 8000)).await?;
// Write some data asynchronously
poll_fn(|cx| unsafe { stream.poll_write_with(cx, |mut s| s.write(b"hello")) }).await?;
Source

pub unsafe fn poll_write_with_mut<'a, P, F>( &'a mut self, cx: &mut Context<'_>, f: F, ) -> Poll<Result<P>>
where F: FnOnce(&'a mut T) -> Result<P>,

Same as Self::poll_write_with, but takes a mutable reference in the closure

§Safety

The closure must not drop the underlying I/O object.

Source

pub async fn writable(&self) -> Result<()>

Waits until the I/O object is available to write without blocking

Source

pub async fn readable(&self) -> Result<()>

Waits until the I/O object is available to read without blocking

Source§

impl Async<TcpListener>

Source

pub fn bind<A: Into<SocketAddr>>(addr: A) -> Result<Self>

Create a TCP listener bound to a specific address

§Example

Bind the TCP listener to an OS-assigned port at 127.0.0.1.

use std::net::TcpListener;
use local_runtime::io::Async;

let listener = Async::<TcpListener>::bind(([127, 0, 0, 1], 0))?;
Source

pub async fn accept(&self) -> Result<(Async<TcpStream>, SocketAddr)>

Accept a new incoming TCP connection from this listener

§Example
use std::net::TcpListener;
use local_runtime::io::Async;

let listener = Async::<TcpListener>::bind(([127, 0, 0, 1], 0))?;
let (stream, addr) = listener.accept().await?;
Source

pub fn incoming(&self) -> IncomingTcp<'_>

Return a stream of incoming TCP connections

The returned stream will never return None.

§Example
use std::net::TcpListener;
use local_runtime::io::Async;
use futures_lite::StreamExt;

let listener = Async::<TcpListener>::bind(([127, 0, 0, 1], 0))?;
let mut incoming = listener.incoming();
while let Some(stream) = incoming.next().await {
    let stream = stream?;
}
Source§

impl Async<TcpStream>

Source

pub async fn connect<A: Into<SocketAddr>>(addr: A) -> Result<Self>

Create a TCP connection to the specified address

use std::net::TcpStream;
use local_runtime::io::Async;

let listener = Async::<TcpStream>::connect(([127, 0, 0, 1], 8000)).await?;
Source

pub async fn peek(&self, buf: &mut [u8]) -> Result<usize>

Reads data from the stream without removing it from the buffer.

Returns the number of bytes read. Successive calls of this method read the same data.

Source§

impl Async<UdpSocket>

Source

pub fn bind<A: Into<SocketAddr>>(addr: A) -> Result<Async<UdpSocket>>

Create a UDP socket from the given address

§Example
use std::net::UdpSocket;
use local_runtime::io::Async;

let socket = Async::<UdpSocket>::bind(([127, 0, 0, 1], 0))?;
println!("Bound to {}", socket.get_ref().local_addr()?);
Source

pub async fn recv_from(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr)>

Receives a single datagram message on a socket

Returns the number of bytes read and the origin address.

The function must be called with valid byte array buf of sufficient size to hold the message bytes. If a message is too long to fit in the supplied buffer, excess bytes may be discarded.

§Example
use std::net::UdpSocket;
use local_runtime::io::Async;

let socket = Async::<UdpSocket>::bind(([127, 0, 0, 1], 0))?;

let mut buf = [0u8; 1024];
let (len, addr) = socket.recv_from(&mut buf).await?;
Source

pub async fn peek_from(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr)>

Receives a single datagram message without removing it from the queue

Returns the number of bytes read and the origin address.

The function must be called with valid byte array buf of sufficient size to hold the message bytes. If a message is too long to fit in the supplied buffer, excess bytes may be discarded.

Source

pub async fn send_to<A: Into<SocketAddr>>( &self, buf: &[u8], addr: A, ) -> Result<usize>

Send data to the specified address

Return the number of bytes written

§Example
use std::net::UdpSocket;
use local_runtime::io::Async;

let socket = Async::<UdpSocket>::bind(([127, 0, 0, 1], 0))?;
let addr = socket.get_ref().local_addr()?;

let len = socket.send_to(b"hello", addr).await?;
Source

pub fn connect<A: Into<SocketAddr>>(&self, addr: A) -> Result<()>

Connect this UDP socket to a remote address, allowing the send and recv methods to be called

Also applies filters to only receive data from the specified address.

Source

pub async fn recv(&self, buf: &mut [u8]) -> Result<usize>

Receives a single datagram message from the connected peer

Returns the number of bytes read.

The function must be called with valid byte array buf of sufficient size to hold the message bytes. If a message is too long to fit in the supplied buffer, excess bytes may be discarded.

This method should only be called after connecting the socket to a remote address via the connect method.

§Example
use std::net::UdpSocket;
use local_runtime::io::Async;

let socket = Async::<UdpSocket>::bind(([127, 0, 0, 1], 0))?;
socket.connect(([127, 0, 0, 1], 9000))?;

let mut buf = [0u8; 1024];
let len = socket.recv(&mut buf).await?;
Source

pub async fn peek(&self, buf: &mut [u8]) -> Result<usize>

Receives a single datagram message from the connected peer without removing it from the queue

Returns the number of bytes read.

The function must be called with valid byte array buf of sufficient size to hold the message bytes. If a message is too long to fit in the supplied buffer, excess bytes may be discarded.

This method should only be called after connecting the socket to a remote address via the connect method.

Source

pub async fn send(&self, buf: &[u8]) -> Result<usize>

Send data to the connected peer

Return the number of bytes written.

This method should only be called after connecting the socket to a remote address via the connect method.

§Example
use std::net::UdpSocket;
use local_runtime::io::Async;

let socket = Async::<UdpSocket>::bind(([127, 0, 0, 1], 0))?;
socket.connect(([127, 0, 0, 1], 9000))?;

let len = socket.send(b"hello").await?;

Trait Implementations§

Source§

impl<T: BufRead + IoSafe> AsyncBufRead for Async<T>

Source§

fn poll_fill_buf( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Result<&[u8]>>

Attempt to return the contents of the internal buffer, filling it with more data from the inner reader if it is empty. Read more
Source§

fn consume(self: Pin<&mut Self>, amt: usize)

Tells this buffer that amt bytes have been consumed from the buffer, so they should no longer be returned in calls to poll_read. Read more
Source§

impl<'a, T> AsyncRead for &'a Async<T>
where &'a T: Read + IoSafe,

Source§

fn poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8], ) -> Poll<Result<usize>>

Attempt to read from the AsyncRead into buf. Read more
Source§

fn poll_read_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>], ) -> Poll<Result<usize, Error>>

Attempt to read from the AsyncRead into bufs using vectored IO operations. Read more
Source§

impl<T: Read + IoSafe> AsyncRead for Async<T>

Source§

fn poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8], ) -> Poll<Result<usize>>

Attempt to read from the AsyncRead into buf. Read more
Source§

fn poll_read_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>], ) -> Poll<Result<usize, Error>>

Attempt to read from the AsyncRead into bufs using vectored IO operations. Read more
Source§

impl<'a, T> AsyncWrite for &'a Async<T>
where &'a T: Write + IoSafe,

Source§

fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll<Result<usize>>

Attempt to write bytes from buf into the object. Read more
Source§

fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>>

Attempt to flush the object, ensuring that any buffered data reach their destination. Read more
Source§

fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>>

Attempt to close the object. Read more
Source§

fn poll_write_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll<Result<usize, Error>>

Attempt to write bytes from bufs into the object using vectored IO operations. Read more
Source§

impl<T: Write + IoSafe> AsyncWrite for Async<T>

Source§

fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll<Result<usize>>

Attempt to write bytes from buf into the object. Read more
Source§

fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>>

Attempt to flush the object, ensuring that any buffered data reach their destination. Read more
Source§

fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>>

Attempt to close the object. Read more
Source§

fn poll_write_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll<Result<usize, Error>>

Attempt to write bytes from bufs into the object using vectored IO operations. Read more
Source§

impl<T> Unpin for Async<T>

Auto Trait Implementations§

§

impl<T> Freeze for Async<T>
where T: Freeze,

§

impl<T> RefUnwindSafe for Async<T>
where T: RefUnwindSafe,

§

impl<T> !Send for Async<T>

§

impl<T> !Sync for Async<T>

§

impl<T> UnwindSafe for Async<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.