[−][src]Struct tokio::io::unix::AsyncFd
Associates an IO object backed by a Unix file descriptor with the tokio
reactor, allowing for readiness to be polled. The file descriptor must be of
a type that can be used with the OS polling facilities (ie, poll
, epoll
,
kqueue
, etc), such as a network socket or pipe.
Creating an AsyncFd registers the file descriptor with the current tokio Reactor, allowing you to directly await the file descriptor being readable or writable. Once registered, the file descriptor remains registered until the AsyncFd is dropped.
The AsyncFd takes ownership of an arbitrary object to represent the IO
object. It is intended that this object will handle closing the file
descriptor when it is dropped, avoiding resource leaks and ensuring that the
AsyncFd can clean up the registration before closing the file descriptor.
The AsyncFd::into_inner
function can be used to extract the inner object
to retake control from the tokio IO reactor.
The inner object is required to implement AsRawFd
. This file descriptor
must not change while AsyncFd
owns the inner object. Changing the file
descriptor results in unspecified behavior in the IO driver, which may
include breaking notifications for other sockets/etc.
Polling for readiness is done by calling the async functions readable
and writable
. These functions complete when the associated readiness
condition is observed. Any number of tasks can query the same AsyncFd
in
parallel, on the same or different conditions.
On some platforms, the readiness detecting mechanism relies on
edge-triggered notifications. This means that the OS will only notify Tokio
when the file descriptor transitions from not-ready to ready. Tokio
internally tracks when it has received a ready notification, and when
readiness checking functions like readable
and writable
are called,
if the readiness flag is set, these async functions will complete
immediately.
This however does mean that it is critical to ensure that this ready flag is
cleared when (and only when) the file descriptor ceases to be ready. The
AsyncFdReadyGuard
returned from readiness checking functions serves this
function; after calling a readiness-checking async function, you must use
this AsyncFdReadyGuard
to signal to tokio whether the file descriptor is no
longer in a ready state.
Use with to a poll-based API
In some cases it may be desirable to use AsyncFd
from APIs similar to
TcpStream::poll_read_ready
. The AsyncFd::poll_read_ready
and
AsyncFd::poll_write_ready
functions are provided for this purpose.
Because these functions don't create a future to hold their state, they have
the limitation that only one task can wait on each direction (read or write)
at a time.
Examples
This example shows how to turn std::net::TcpStream
asynchronous using
AsyncFd
. It implements read
as an async fn, and AsyncWrite
as a trait
to show how to implement both approaches.
use futures::ready; use std::io::{self, Read, Write}; use std::net::TcpStream; use std::pin::Pin; use std::task::{Context, Poll}; use tokio::io::AsyncWrite; use tokio::io::unix::AsyncFd; pub struct AsyncTcpStream { inner: AsyncFd<TcpStream>, } impl AsyncTcpStream { pub fn new(tcp: TcpStream) -> io::Result<Self> { Ok(Self { inner: AsyncFd::new(tcp)?, }) } pub async fn read(&self, out: &mut [u8]) -> io::Result<usize> { loop { let mut guard = self.inner.readable().await?; match guard.try_io(|inner| inner.get_ref().read(out)) { Ok(result) => return result, Err(_would_block) => continue, } } } } impl AsyncWrite for AsyncTcpStream { fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8] ) -> Poll<io::Result<usize>> { loop { let mut guard = ready!(self.inner.poll_write_ready(cx))?; match guard.try_io(|inner| inner.get_ref().write(buf)) { Ok(result) => return Poll::Ready(result), Err(_would_block) => continue, } } } fn poll_flush( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<io::Result<()>> { // tcp flush is a no-op Poll::Ready(Ok(())) } fn poll_shutdown( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<io::Result<()>> { self.inner.get_ref().shutdown(std::net::Shutdown::Write)?; Poll::Ready(Ok(())) } }
Implementations
impl<T: AsRawFd> AsyncFd<T>
[src]
pub fn new(inner: T) -> Result<Self> where
T: AsRawFd,
[src]
T: AsRawFd,
Creates an AsyncFd backed by (and taking ownership of) an object
implementing AsRawFd
. The backing file descriptor is cached at the
time of creation.
This method must be called in the context of a tokio runtime.
pub fn with_interest(inner: T, interest: Interest) -> Result<Self> where
T: AsRawFd,
[src]
T: AsRawFd,
Creates new instance as new
with additional ability to customize interest,
allowing to specify whether file descriptor will be polled for read, write or both.
pub fn get_ref(&self) -> &Tⓘ
[src]
Returns a shared reference to the backing object of this AsyncFd
pub fn get_mut(&mut self) -> &mut Tⓘ
[src]
Returns a mutable reference to the backing object of this AsyncFd
pub fn into_inner(self) -> T
[src]
Deregisters this file descriptor and returns ownership of the backing object.
pub fn poll_read_ready<'a>(
&'a self,
cx: &mut Context<'_>
) -> Poll<Result<AsyncFdReadyGuard<'a, T>>>
[src]
&'a self,
cx: &mut Context<'_>
) -> Poll<Result<AsyncFdReadyGuard<'a, T>>>
Polls for read readiness.
If the file descriptor is not currently ready for reading, this method
will store a clone of the Waker
from the provided Context
. When the
file descriptor becomes ready for reading, Waker::wake
will be called.
Note that on multiple calls to poll_read_ready
or
poll_read_ready_mut
, only the Waker
from the Context
passed to the
most recent call is scheduled to receive a wakeup. (However,
poll_write_ready
retains a second, independent waker).
This method is intended for cases where creating and pinning a future
via readable
is not feasible. Where possible, using readable
is
preferred, as this supports polling from multiple tasks at once.
This method takes &self
, so it is possible to call this method
concurrently with other methods on this struct. This method only
provides shared access to the inner IO resource when handling the
AsyncFdReadyGuard
.
pub fn poll_read_ready_mut<'a>(
&'a mut self,
cx: &mut Context<'_>
) -> Poll<Result<AsyncFdReadyMutGuard<'a, T>>>
[src]
&'a mut self,
cx: &mut Context<'_>
) -> Poll<Result<AsyncFdReadyMutGuard<'a, T>>>
Polls for read readiness.
If the file descriptor is not currently ready for reading, this method
will store a clone of the Waker
from the provided Context
. When the
file descriptor becomes ready for reading, Waker::wake
will be called.
Note that on multiple calls to poll_read_ready
or
poll_read_ready_mut
, only the Waker
from the Context
passed to the
most recent call is scheduled to receive a wakeup. (However,
poll_write_ready
retains a second, independent waker).
This method is intended for cases where creating and pinning a future
via readable
is not feasible. Where possible, using readable
is
preferred, as this supports polling from multiple tasks at once.
This method takes &mut self
, so it is possible to access the inner IO
resource mutably when handling the AsyncFdReadyMutGuard
.
pub fn poll_write_ready<'a>(
&'a self,
cx: &mut Context<'_>
) -> Poll<Result<AsyncFdReadyGuard<'a, T>>>
[src]
&'a self,
cx: &mut Context<'_>
) -> Poll<Result<AsyncFdReadyGuard<'a, T>>>
Polls for write readiness.
If the file descriptor is not currently ready for writing, this method
will store a clone of the Waker
from the provided Context
. When the
file descriptor becomes ready for writing, Waker::wake
will be called.
Note that on multiple calls to poll_write_ready
or
poll_write_ready_mut
, only the Waker
from the Context
passed to the
most recent call is scheduled to receive a wakeup. (However,
poll_read_ready
retains a second, independent waker).
This method is intended for cases where creating and pinning a future
via writable
is not feasible. Where possible, using writable
is
preferred, as this supports polling from multiple tasks at once.
This method takes &self
, so it is possible to call this method
concurrently with other methods on this struct. This method only
provides shared access to the inner IO resource when handling the
AsyncFdReadyGuard
.
pub fn poll_write_ready_mut<'a>(
&'a mut self,
cx: &mut Context<'_>
) -> Poll<Result<AsyncFdReadyMutGuard<'a, T>>>
[src]
&'a mut self,
cx: &mut Context<'_>
) -> Poll<Result<AsyncFdReadyMutGuard<'a, T>>>
Polls for write readiness.
If the file descriptor is not currently ready for writing, this method
will store a clone of the Waker
from the provided Context
. When the
file descriptor becomes ready for writing, Waker::wake
will be called.
Note that on multiple calls to poll_write_ready
or
poll_write_ready_mut
, only the Waker
from the Context
passed to the
most recent call is scheduled to receive a wakeup. (However,
poll_read_ready
retains a second, independent waker).
This method is intended for cases where creating and pinning a future
via writable
is not feasible. Where possible, using writable
is
preferred, as this supports polling from multiple tasks at once.
This method takes &mut self
, so it is possible to access the inner IO
resource mutably when handling the AsyncFdReadyMutGuard
.
pub async fn readable<'a>(&'a self) -> Result<AsyncFdReadyGuard<'a, T>>
[src]
Waits for the file descriptor to become readable, returning a
AsyncFdReadyGuard
that must be dropped to resume read-readiness
polling.
This method takes &self
, so it is possible to call this method
concurrently with other methods on this struct. This method only
provides shared access to the inner IO resource when handling the
AsyncFdReadyGuard
.
pub async fn readable_mut<'a>(
&'a mut self
) -> Result<AsyncFdReadyMutGuard<'a, T>>
[src]
&'a mut self
) -> Result<AsyncFdReadyMutGuard<'a, T>>
Waits for the file descriptor to become readable, returning a
AsyncFdReadyMutGuard
that must be dropped to resume read-readiness
polling.
This method takes &mut self
, so it is possible to access the inner IO
resource mutably when handling the AsyncFdReadyMutGuard
.
pub async fn writable<'a>(&'a self) -> Result<AsyncFdReadyGuard<'a, T>>
[src]
Waits for the file descriptor to become writable, returning a
AsyncFdReadyGuard
that must be dropped to resume write-readiness
polling.
This method takes &self
, so it is possible to call this method
concurrently with other methods on this struct. This method only
provides shared access to the inner IO resource when handling the
AsyncFdReadyGuard
.
pub async fn writable_mut<'a>(
&'a mut self
) -> Result<AsyncFdReadyMutGuard<'a, T>>
[src]
&'a mut self
) -> Result<AsyncFdReadyMutGuard<'a, T>>
Waits for the file descriptor to become writable, returning a
AsyncFdReadyMutGuard
that must be dropped to resume write-readiness
polling.
This method takes &mut self
, so it is possible to access the inner IO
resource mutably when handling the AsyncFdReadyMutGuard
.
Trait Implementations
impl<T: AsRawFd> AsRawFd for AsyncFd<T>
[src]
impl<T: Debug + AsRawFd> Debug for AsyncFd<T>
[src]
impl<T: AsRawFd> Drop for AsyncFd<T>
[src]
Auto Trait Implementations
impl<T> !RefUnwindSafe for AsyncFd<T>
impl<T> Send for AsyncFd<T> where
T: Send,
T: Send,
impl<T> Sync for AsyncFd<T> where
T: Sync,
T: Sync,
impl<T> Unpin for AsyncFd<T> where
T: Unpin,
T: Unpin,
impl<T> !UnwindSafe for AsyncFd<T>
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut Tⓘ
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,