Files
blackwriter-server/doc/tokio.md

14682 lines
357 KiB
Markdown
Raw Normal View History

2025-12-13 21:43:14 +03:00
# Crate Documentation
**Version:** 1.48.0
**Format Version:** 56
# Module `tokio`
A runtime for writing reliable network applications without compromising speed.
Tokio is an event-driven, non-blocking I/O platform for writing asynchronous
applications with the Rust programming language. At a high level, it
provides a few major components:
* Tools for [working with asynchronous tasks][tasks], including
[synchronization primitives and channels][sync] and [timeouts, sleeps, and
intervals][time].
* APIs for [performing asynchronous I/O][io], including [TCP and UDP][net] sockets,
[filesystem][fs] operations, and [process] and [signal] management.
* A [runtime] for executing asynchronous code, including a task scheduler,
an I/O driver backed by the operating system's event queue (`epoll`, `kqueue`,
`IOCP`, etc...), and a high performance timer.
Guide level documentation is found on the [website].
[tasks]: #working-with-tasks
[sync]: crate::sync
[time]: crate::time
[io]: #asynchronous-io
[net]: crate::net
[fs]: crate::fs
[process]: crate::process
[signal]: crate::signal
[fs]: crate::fs
[runtime]: crate::runtime
[website]: https://tokio.rs/tokio/tutorial
# A Tour of Tokio
Tokio consists of a number of modules that provide a range of functionality
essential for implementing asynchronous applications in Rust. In this
section, we will take a brief tour of Tokio, summarizing the major APIs and
their uses.
The easiest way to get started is to enable all features. Do this by
enabling the `full` feature flag:
```toml
tokio = { version = "1", features = ["full"] }
```
### Authoring applications
Tokio is great for writing applications and most users in this case shouldn't
worry too much about what features they should pick. If you're unsure, we suggest
going with `full` to ensure that you don't run into any road blocks while you're
building your application.
#### Example
This example shows the quickest way to get started with Tokio.
```toml
tokio = { version = "1", features = ["full"] }
```
### Authoring libraries
As a library author your goal should be to provide the lightest weight crate
that is based on Tokio. To achieve this you should ensure that you only enable
the features you need. This allows users to pick up your crate without having
to enable unnecessary features.
#### Example
This example shows how you may want to import features for a library that just
needs to `tokio::spawn` and use a `TcpStream`.
```toml
tokio = { version = "1", features = ["rt", "net"] }
```
## Working With Tasks
Asynchronous programs in Rust are based around lightweight, non-blocking
units of execution called [_tasks_][tasks]. The [`tokio::task`] module provides
important tools for working with tasks:
* The [`spawn`] function and [`JoinHandle`] type, for scheduling a new task
on the Tokio runtime and awaiting the output of a spawned task, respectively,
* Functions for [running blocking operations][blocking] in an asynchronous
task context.
The [`tokio::task`] module is present only when the "rt" feature flag
is enabled.
[tasks]: task/index.html#what-are-tasks
[`tokio::task`]: crate::task
[`spawn`]: crate::task::spawn()
[`JoinHandle`]: crate::task::JoinHandle
[blocking]: task/index.html#blocking-and-yielding
The [`tokio::sync`] module contains synchronization primitives to use when
needing to communicate or share data. These include:
* channels ([`oneshot`], [`mpsc`], [`watch`], and [`broadcast`]), for sending values
between tasks,
* a non-blocking [`Mutex`], for controlling access to a shared, mutable
value,
* an asynchronous [`Barrier`] type, for multiple tasks to synchronize before
beginning a computation.
The `tokio::sync` module is present only when the "sync" feature flag is
enabled.
[`tokio::sync`]: crate::sync
[`Mutex`]: crate::sync::Mutex
[`Barrier`]: crate::sync::Barrier
[`oneshot`]: crate::sync::oneshot
[`mpsc`]: crate::sync::mpsc
[`watch`]: crate::sync::watch
[`broadcast`]: crate::sync::broadcast
The [`tokio::time`] module provides utilities for tracking time and
scheduling work. This includes functions for setting [timeouts][timeout] for
tasks, [sleeping][sleep] work to run in the future, or [repeating an operation at an
interval][interval].
In order to use `tokio::time`, the "time" feature flag must be enabled.
[`tokio::time`]: crate::time
[sleep]: crate::time::sleep()
[interval]: crate::time::interval()
[timeout]: crate::time::timeout()
Finally, Tokio provides a _runtime_ for executing asynchronous tasks. Most
applications can use the [`#[tokio::main]`][main] macro to run their code on the
Tokio runtime. However, this macro provides only basic configuration options. As
an alternative, the [`tokio::runtime`] module provides more powerful APIs for configuring
and managing runtimes. You should use that module if the `#[tokio::main]` macro doesn't
provide the functionality you need.
Using the runtime requires the "rt" or "rt-multi-thread" feature flags, to
enable the current-thread [single-threaded scheduler][rt] and the [multi-thread
scheduler][rt-multi-thread], respectively. See the [`runtime` module
documentation][rt-features] for details. In addition, the "macros" feature
flag enables the `#[tokio::main]` and `#[tokio::test]` attributes.
[main]: attr.main.html
[`tokio::runtime`]: crate::runtime
[`Builder`]: crate::runtime::Builder
[`Runtime`]: crate::runtime::Runtime
[rt]: runtime/index.html#current-thread-scheduler
[rt-multi-thread]: runtime/index.html#multi-thread-scheduler
[rt-features]: runtime/index.html#runtime-scheduler
## CPU-bound tasks and blocking code
Tokio is able to concurrently run many tasks on a few threads by repeatedly
swapping the currently running task on each thread. However, this kind of
swapping can only happen at `.await` points, so code that spends a long time
without reaching an `.await` will prevent other tasks from running. To
combat this, Tokio provides two kinds of threads: Core threads and blocking threads.
The core threads are where all asynchronous code runs, and Tokio will by default
spawn one for each CPU core. You can use the environment variable `TOKIO_WORKER_THREADS`
to override the default value.
The blocking threads are spawned on demand, can be used to run blocking code
that would otherwise block other tasks from running and are kept alive when
not used for a certain amount of time which can be configured with [`thread_keep_alive`].
Since it is not possible for Tokio to swap out blocking tasks, like it
can do with asynchronous code, the upper limit on the number of blocking
threads is very large. These limits can be configured on the [`Builder`].
To spawn a blocking task, you should use the [`spawn_blocking`] function.
[`Builder`]: crate::runtime::Builder
[`spawn_blocking`]: crate::task::spawn_blocking()
[`thread_keep_alive`]: crate::runtime::Builder::thread_keep_alive()
```
# #[cfg(not(target_family = "wasm"))]
# {
#[tokio::main]
async fn main() {
// This is running on a core thread.
let blocking_task = tokio::task::spawn_blocking(|| {
// This is running on a blocking thread.
// Blocking here is ok.
});
// We can wait for the blocking task like this:
// If the blocking task panics, the unwrap below will propagate the
// panic.
blocking_task.await.unwrap();
}
# }
```
If your code is CPU-bound and you wish to limit the number of threads used
to run it, you should use a separate thread pool dedicated to CPU bound tasks.
For example, you could consider using the [rayon] library for CPU-bound
tasks. It is also possible to create an extra Tokio runtime dedicated to
CPU-bound tasks, but if you do this, you should be careful that the extra
runtime runs _only_ CPU-bound tasks, as IO-bound tasks on that runtime
will behave poorly.
Hint: If using rayon, you can use a [`oneshot`] channel to send the result back
to Tokio when the rayon task finishes.
[rayon]: https://docs.rs/rayon
[`oneshot`]: crate::sync::oneshot
## Asynchronous IO
As well as scheduling and running tasks, Tokio provides everything you need
to perform input and output asynchronously.
The [`tokio::io`] module provides Tokio's asynchronous core I/O primitives,
the [`AsyncRead`], [`AsyncWrite`], and [`AsyncBufRead`] traits. In addition,
when the "io-util" feature flag is enabled, it also provides combinators and
functions for working with these traits, forming as an asynchronous
counterpart to [`std::io`].
Tokio also includes APIs for performing various kinds of I/O and interacting
with the operating system asynchronously. These include:
* [`tokio::net`], which contains non-blocking versions of [TCP], [UDP], and
[Unix Domain Sockets][UDS] (enabled by the "net" feature flag),
* [`tokio::fs`], similar to [`std::fs`] but for performing filesystem I/O
asynchronously (enabled by the "fs" feature flag),
* [`tokio::signal`], for asynchronously handling Unix and Windows OS signals
(enabled by the "signal" feature flag),
* [`tokio::process`], for spawning and managing child processes (enabled by
the "process" feature flag).
[`tokio::io`]: crate::io
[`AsyncRead`]: crate::io::AsyncRead
[`AsyncWrite`]: crate::io::AsyncWrite
[`AsyncBufRead`]: crate::io::AsyncBufRead
[`std::io`]: std::io
[`tokio::net`]: crate::net
[TCP]: crate::net::tcp
[UDP]: crate::net::UdpSocket
[UDS]: crate::net::unix
[`tokio::fs`]: crate::fs
[`std::fs`]: std::fs
[`tokio::signal`]: crate::signal
[`tokio::process`]: crate::process
# Examples
A simple TCP echo server:
```no_run
# #[cfg(not(target_family = "wasm"))]
# {
use tokio::net::TcpListener;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let listener = TcpListener::bind("127.0.0.1:8080").await?;
loop {
let (mut socket, _) = listener.accept().await?;
tokio::spawn(async move {
let mut buf = [0; 1024];
// In a loop, read data from the socket and write the data back.
loop {
let n = match socket.read(&mut buf).await {
// socket closed
Ok(0) => return,
Ok(n) => n,
Err(e) => {
eprintln!("failed to read from socket; err = {:?}", e);
return;
}
};
// Write the data back
if let Err(e) = socket.write_all(&buf[0..n]).await {
eprintln!("failed to write to socket; err = {:?}", e);
return;
}
}
});
}
}
# }
```
# Feature flags
Tokio uses a set of [feature flags] to reduce the amount of compiled code. It
is possible to just enable certain features over others. By default, Tokio
does not enable any features but allows one to enable a subset for their use
case. Below is a list of the available feature flags. You may also notice
above each function, struct and trait there is listed one or more feature flags
that are required for that item to be used. If you are new to Tokio it is
recommended that you use the `full` feature flag which will enable all public APIs.
Beware though that this will pull in many extra dependencies that you may not
need.
- `full`: Enables all features listed below except `test-util` and `tracing`.
- `rt`: Enables `tokio::spawn`, the current-thread scheduler,
and non-scheduler utilities.
- `rt-multi-thread`: Enables the heavier, multi-threaded, work-stealing scheduler.
- `io-util`: Enables the IO based `Ext` traits.
- `io-std`: Enable `Stdout`, `Stdin` and `Stderr` types.
- `net`: Enables `tokio::net` types such as `TcpStream`, `UnixStream` and
`UdpSocket`, as well as (on Unix-like systems) `AsyncFd` and (on
FreeBSD) `PollAio`.
- `time`: Enables `tokio::time` types and allows the schedulers to enable
the built in timer.
- `process`: Enables `tokio::process` types.
- `macros`: Enables `#[tokio::main]` and `#[tokio::test]` macros.
- `sync`: Enables all `tokio::sync` types.
- `signal`: Enables all `tokio::signal` types.
- `fs`: Enables `tokio::fs` types.
- `test-util`: Enables testing based infrastructure for the Tokio runtime.
- `parking_lot`: As a potential optimization, use the [`parking_lot`] crate's
synchronization primitives internally. Also, this
dependency is necessary to construct some of our primitives
in a `const` context. `MSRV` may increase according to the
[`parking_lot`] release in use.
_Note: `AsyncRead` and `AsyncWrite` traits do not require any features and are
always available._
## Unstable features
Some feature flags are only available when specifying the `tokio_unstable` flag:
- `tracing`: Enables tracing events.
Likewise, some parts of the API are only available with the same flag:
- [`task::Builder`]
- Some methods on [`task::JoinSet`]
- [`runtime::RuntimeMetrics`]
- [`runtime::Builder::on_task_spawn`]
- [`runtime::Builder::on_task_terminate`]
- [`runtime::Builder::unhandled_panic`]
- [`runtime::TaskMeta`]
This flag enables **unstable** features. The public API of these features
may break in 1.x releases. To enable these features, the `--cfg
tokio_unstable` argument must be passed to `rustc` when compiling. This
serves to explicitly opt-in to features which may break semver conventions,
since Cargo [does not yet directly support such opt-ins][unstable features].
You can specify it in your project's `.cargo/config.toml` file:
```toml
[build]
rustflags = ["--cfg", "tokio_unstable"]
```
<div class="warning">
The <code>[build]</code> section does <strong>not</strong> go in a
<code>Cargo.toml</code> file. Instead it must be placed in the Cargo config
file <code>.cargo/config.toml</code>.
</div>
Alternatively, you can specify it with an environment variable:
```sh
## Many *nix shells:
export RUSTFLAGS="--cfg tokio_unstable"
cargo build
```
```powershell
## Windows PowerShell:
$Env:RUSTFLAGS="--cfg tokio_unstable"
cargo build
```
[unstable features]: https://internals.rust-lang.org/t/feature-request-unstable-opt-in-non-transitive-crate-features/16193#why-not-a-crate-feature-2
[feature flags]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section
# Supported platforms
Tokio currently guarantees support for the following platforms:
* Linux
* Windows
* Android (API level 21)
* macOS
* iOS
* FreeBSD
Tokio will continue to support these platforms in the future. However,
future releases may change requirements such as the minimum required libc
version on Linux, the API level on Android, or the supported FreeBSD
release.
Beyond the above platforms, Tokio is intended to work on all platforms
supported by the mio crate. You can find a longer list [in mio's
documentation][mio-supported]. However, these additional platforms may
become unsupported in the future.
Note that Wine is considered to be a different platform from Windows. See
mio's documentation for more information on Wine support.
[mio-supported]: https://crates.io/crates/mio#platforms
## `WASM` support
Tokio has some limited support for the `WASM` platform. Without the
`tokio_unstable` flag, the following features are supported:
* `sync`
* `macros`
* `io-util`
* `rt`
* `time`
Enabling any other feature (including `full`) will cause a compilation
failure.
The `time` module will only work on `WASM` platforms that have support for
timers (e.g. wasm32-wasi). The timing functions will panic if used on a `WASM`
platform that does not support timers.
Note also that if the runtime becomes indefinitely idle, it will panic
immediately instead of blocking forever. On platforms that don't support
time, this means that the runtime can never be idle in any way.
## Unstable `WASM` support
Tokio also has unstable support for some additional `WASM` features. This
requires the use of the `tokio_unstable` flag.
Using this flag enables the use of `tokio::net` on the wasm32-wasi target.
However, not all methods are available on the networking types as `WASI`
currently does not support the creation of new sockets from within `WASM`.
Because of this, sockets must currently be created via the `FromRawFd`
trait.
## Modules
## Module `fs`
**Attributes:**
- `Other("#[<cfg>(feature = \"fs\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"fs\")))]")`
- `Other("#[doc(cfg(feature = \"fs\"))]")`
- `Other("#[<cfg>(not(loom))]")`
Asynchronous file utilities.
This module contains utility methods for working with the file system
asynchronously. This includes reading/writing to files, and working with
directories.
Be aware that most operating systems do not provide asynchronous file system
APIs. Because of that, Tokio will use ordinary blocking file operations
behind the scenes. This is done using the [`spawn_blocking`] threadpool to
run them in the background.
The `tokio::fs` module should only be used for ordinary files. Trying to use
it with e.g., a named pipe on Linux can result in surprising behavior,
such as hangs during runtime shutdown. For special files, you should use a
dedicated type such as [`tokio::net::unix::pipe`] or [`AsyncFd`] instead.
Currently, Tokio will always use [`spawn_blocking`] on all platforms, but it
may be changed to use asynchronous file system APIs such as io_uring in the
future.
# Usage
The easiest way to use this module is to use the utility functions that
operate on entire files:
* [`tokio::fs::read`](fn@crate::fs::read)
* [`tokio::fs::read_to_string`](fn@crate::fs::read_to_string)
* [`tokio::fs::write`](fn@crate::fs::write)
The two `read` functions reads the entire file and returns its contents.
The `write` function takes the contents of the file and writes those
contents to the file. It overwrites the existing file, if any.
For example, to read the file:
```
# async fn dox() -> std::io::Result<()> {
let contents = tokio::fs::read_to_string("my_file.txt").await?;
println!("File has {} lines.", contents.lines().count());
# Ok(())
# }
```
To overwrite the file:
```
# async fn dox() -> std::io::Result<()> {
let contents = "First line.\nSecond line.\nThird line.\n";
tokio::fs::write("my_file.txt", contents.as_bytes()).await?;
# Ok(())
# }
```
## Using `File`
The main type for interacting with files is [`File`]. It can be used to read
from and write to a given file. This is done using the [`AsyncRead`] and
[`AsyncWrite`] traits. This type is generally used when you want to do
something more complex than just reading or writing the entire contents in
one go.
**Note:** It is important to use [`flush`] when writing to a Tokio
[`File`]. This is because calls to `write` will return before the write has
finished, and [`flush`] will wait for the write to finish. (The write will
happen even if you don't flush; it will just happen later.) This is
different from [`std::fs::File`], and is due to the fact that `File` uses
`spawn_blocking` behind the scenes.
For example, to count the number of lines in a file without loading the
entire file into memory:
```no_run
use tokio::fs::File;
use tokio::io::AsyncReadExt;
# async fn dox() -> std::io::Result<()> {
let mut file = File::open("my_file.txt").await?;
let mut chunk = vec![0; 4096];
let mut number_of_lines = 0;
loop {
let len = file.read(&mut chunk).await?;
if len == 0 {
// Length of zero means end of file.
break;
}
for &b in &chunk[..len] {
if b == b'\n' {
number_of_lines += 1;
}
}
}
println!("File has {} lines.", number_of_lines);
# Ok(())
# }
```
For example, to write a file line-by-line:
```no_run
use tokio::fs::File;
use tokio::io::AsyncWriteExt;
# async fn dox() -> std::io::Result<()> {
let mut file = File::create("my_file.txt").await?;
file.write_all(b"First line.\n").await?;
file.write_all(b"Second line.\n").await?;
file.write_all(b"Third line.\n").await?;
// Remember to call `flush` after writing!
file.flush().await?;
# Ok(())
# }
```
## Tuning your file IO
Tokio's file uses [`spawn_blocking`] behind the scenes, and this has serious
performance consequences. To get good performance with file IO on Tokio, it
is recommended to batch your operations into as few `spawn_blocking` calls
as possible.
One example of this difference can be seen by comparing the two reading
examples above. The first example uses [`tokio::fs::read`], which reads the
entire file in a single `spawn_blocking` call, and then returns it. The
second example will read the file in chunks using many `spawn_blocking`
calls. This means that the second example will most likely be more expensive
for large files. (Of course, using chunks may be necessary for very large
files that don't fit in memory.)
The following examples will show some strategies for this:
When creating a file, write the data to a `String` or `Vec<u8>` and then
write the entire file in a single `spawn_blocking` call with
`tokio::fs::write`.
```no_run
# async fn dox() -> std::io::Result<()> {
let mut contents = String::new();
contents.push_str("First line.\n");
contents.push_str("Second line.\n");
contents.push_str("Third line.\n");
tokio::fs::write("my_file.txt", contents.as_bytes()).await?;
# Ok(())
# }
```
Use [`BufReader`] and [`BufWriter`] to buffer many small reads or writes
into a few large ones. This example will most likely only perform one
`spawn_blocking` call.
```no_run
use tokio::fs::File;
use tokio::io::{AsyncWriteExt, BufWriter};
# async fn dox() -> std::io::Result<()> {
let mut file = BufWriter::new(File::create("my_file.txt").await?);
file.write_all(b"First line.\n").await?;
file.write_all(b"Second line.\n").await?;
file.write_all(b"Third line.\n").await?;
// Due to the BufWriter, the actual write and spawn_blocking
// call happens when you flush.
file.flush().await?;
# Ok(())
# }
```
Manually use [`std::fs`] inside [`spawn_blocking`].
```no_run
use std::fs::File;
use std::io::{self, Write};
use tokio::task::spawn_blocking;
# async fn dox() -> std::io::Result<()> {
spawn_blocking(move || {
let mut file = File::create("my_file.txt")?;
file.write_all(b"First line.\n")?;
file.write_all(b"Second line.\n")?;
file.write_all(b"Third line.\n")?;
// Unlike Tokio's file, the std::fs file does
// not need flush.
io::Result::Ok(())
}).await.unwrap()?;
# Ok(())
# }
```
It's also good to be aware of [`File::set_max_buf_size`], which controls the
maximum amount of bytes that Tokio's [`File`] will read or write in a single
[`spawn_blocking`] call. The default is two megabytes, but this is subject
to change.
[`spawn_blocking`]: fn@crate::task::spawn_blocking
[`AsyncRead`]: trait@crate::io::AsyncRead
[`AsyncWrite`]: trait@crate::io::AsyncWrite
[`BufReader`]: struct@crate::io::BufReader
[`BufWriter`]: struct@crate::io::BufWriter
[`tokio::net::unix::pipe`]: crate::net::unix::pipe
[`AsyncFd`]: crate::io::unix::AsyncFd
[`flush`]: crate::io::AsyncWriteExt::flush
[`tokio::fs::read`]: fn@crate::fs::read
```rust
pub mod fs { /* ... */ }
```
### Re-exports
#### Re-export `canonicalize`
```rust
pub use self::canonicalize::canonicalize;
```
#### Re-export `create_dir`
```rust
pub use self::create_dir::create_dir;
```
#### Re-export `create_dir_all`
```rust
pub use self::create_dir_all::create_dir_all;
```
#### Re-export `DirBuilder`
```rust
pub use self::dir_builder::DirBuilder;
```
#### Re-export `File`
```rust
pub use self::file::File;
```
#### Re-export `hard_link`
```rust
pub use self::hard_link::hard_link;
```
#### Re-export `metadata`
```rust
pub use self::metadata::metadata;
```
#### Re-export `OpenOptions`
```rust
pub use self::open_options::OpenOptions;
```
#### Re-export `read`
```rust
pub use self::read::read;
```
#### Re-export `read_dir`
```rust
pub use self::read_dir::read_dir;
```
#### Re-export `DirEntry`
```rust
pub use self::read_dir::DirEntry;
```
#### Re-export `ReadDir`
```rust
pub use self::read_dir::ReadDir;
```
#### Re-export `read_link`
```rust
pub use self::read_link::read_link;
```
#### Re-export `read_to_string`
```rust
pub use self::read_to_string::read_to_string;
```
#### Re-export `remove_dir`
```rust
pub use self::remove_dir::remove_dir;
```
#### Re-export `remove_dir_all`
```rust
pub use self::remove_dir_all::remove_dir_all;
```
#### Re-export `remove_file`
```rust
pub use self::remove_file::remove_file;
```
#### Re-export `rename`
```rust
pub use self::rename::rename;
```
#### Re-export `set_permissions`
```rust
pub use self::set_permissions::set_permissions;
```
#### Re-export `symlink_metadata`
```rust
pub use self::symlink_metadata::symlink_metadata;
```
#### Re-export `write`
```rust
pub use self::write::write;
```
#### Re-export `copy`
```rust
pub use self::copy::copy;
```
#### Re-export `try_exists`
```rust
pub use self::try_exists::try_exists;
```
#### Re-export `symlink`
**Attributes:**
- `Other("#[<cfg>(unix)]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(unix)))]")`
- `Other("#[doc(cfg(unix))]")`
```rust
pub use self::symlink::symlink;
```
#### Re-export `symlink_dir`
**Attributes:**
- `Other("#[<cfg>(any(all(doc, docsrs), windows))]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(windows)))]")`
- `Other("#[doc(cfg(windows))]")`
```rust
pub use self::symlink_dir::symlink_dir;
```
#### Re-export `symlink_file`
**Attributes:**
- `Other("#[<cfg>(any(all(doc, docsrs), windows))]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(windows)))]")`
- `Other("#[doc(cfg(windows))]")`
```rust
pub use self::symlink_file::symlink_file;
```
## Module `io`
**Attributes:**
- `Other("#[<cfg_attr>(not(all(feature = \"rt\", feature = \"net\")),\nallow(dead_code, unused_imports))]")`
Traits, helpers, and type definitions for asynchronous I/O functionality.
This module is the asynchronous version of `std::io`. Primarily, it
defines two traits, [`AsyncRead`] and [`AsyncWrite`], which are asynchronous
versions of the [`Read`] and [`Write`] traits in the standard library.
# `AsyncRead` and `AsyncWrite`
Like the standard library's [`Read`] and [`Write`] traits, [`AsyncRead`] and
[`AsyncWrite`] provide the most general interface for reading and writing
input and output. Unlike the standard library's traits, however, they are
_asynchronous_ &mdash; meaning that reading from or writing to a `tokio::io`
type will _yield_ to the Tokio scheduler when IO is not ready, rather than
blocking. This allows other tasks to run while waiting on IO.
Another difference is that `AsyncRead` and `AsyncWrite` only contain
core methods needed to provide asynchronous reading and writing
functionality. Instead, utility methods are defined in the [`AsyncReadExt`]
and [`AsyncWriteExt`] extension traits. These traits are automatically
implemented for all values that implement `AsyncRead` and `AsyncWrite`
respectively.
End users will rarely interact directly with `AsyncRead` and
`AsyncWrite`. Instead, they will use the async functions defined in the
extension traits. Library authors are expected to implement `AsyncRead`
and `AsyncWrite` in order to provide types that behave like byte streams.
Even with these differences, Tokio's `AsyncRead` and `AsyncWrite` traits
can be used in almost exactly the same manner as the standard library's
`Read` and `Write`. Most types in the standard library that implement `Read`
and `Write` have asynchronous equivalents in `tokio` that implement
`AsyncRead` and `AsyncWrite`, such as [`File`] and [`TcpStream`].
For example, the standard library documentation introduces `Read` by
[demonstrating][std_example] reading some bytes from a [`std::fs::File`]. We
can do the same with [`tokio::fs::File`][`File`]:
```no_run
# #[cfg(not(target_family = "wasm"))]
# {
use tokio::io::{self, AsyncReadExt};
use tokio::fs::File;
#[tokio::main]
async fn main() -> io::Result<()> {
let mut f = File::open("foo.txt").await?;
let mut buffer = [0; 10];
// read up to 10 bytes
let n = f.read(&mut buffer).await?;
println!("The bytes: {:?}", &buffer[..n]);
Ok(())
}
# }
```
[`File`]: crate::fs::File
[`TcpStream`]: crate::net::TcpStream
[`std::fs::File`]: std::fs::File
[std_example]: std::io#read-and-write
## Buffered Readers and Writers
Byte-based interfaces are unwieldy and can be inefficient, as we'd need to be
making near-constant calls to the operating system. To help with this,
`std::io` comes with [support for _buffered_ readers and writers][stdbuf],
and therefore, `tokio::io` does as well.
Tokio provides an async version of the [`std::io::BufRead`] trait,
[`AsyncBufRead`]; and async [`BufReader`] and [`BufWriter`] structs, which
wrap readers and writers. These wrappers use a buffer, reducing the number
of calls and providing nicer methods for accessing exactly what you want.
For example, [`BufReader`] works with the [`AsyncBufRead`] trait to add
extra methods to any async reader:
```no_run
# #[cfg(not(target_family = "wasm"))]
# {
use tokio::io::{self, BufReader, AsyncBufReadExt};
use tokio::fs::File;
#[tokio::main]
async fn main() -> io::Result<()> {
let f = File::open("foo.txt").await?;
let mut reader = BufReader::new(f);
let mut buffer = String::new();
// read a line into buffer
reader.read_line(&mut buffer).await?;
println!("{}", buffer);
Ok(())
}
# }
```
[`BufWriter`] doesn't add any new ways of writing; it just buffers every call
to [`write`](crate::io::AsyncWriteExt::write). However, you **must** flush
[`BufWriter`] to ensure that any buffered data is written.
```no_run
# #[cfg(not(target_family = "wasm"))]
# {
use tokio::io::{self, BufWriter, AsyncWriteExt};
use tokio::fs::File;
#[tokio::main]
async fn main() -> io::Result<()> {
let f = File::create("foo.txt").await?;
{
let mut writer = BufWriter::new(f);
// Write a byte to the buffer.
writer.write(&[42u8]).await?;
// Flush the buffer before it goes out of scope.
writer.flush().await?;
} // Unless flushed or shut down, the contents of the buffer is discarded on drop.
Ok(())
}
# }
```
[stdbuf]: std::io#bufreader-and-bufwriter
[`std::io::BufRead`]: std::io::BufRead
[`AsyncBufRead`]: crate::io::AsyncBufRead
[`BufReader`]: crate::io::BufReader
[`BufWriter`]: crate::io::BufWriter
## Implementing `AsyncRead` and `AsyncWrite`
Because they are traits, we can implement [`AsyncRead`] and [`AsyncWrite`] for
our own types, as well. Note that these traits must only be implemented for
non-blocking I/O types that integrate with the futures type system. In
other words, these types must never block the thread, and instead the
current task is notified when the I/O resource is ready.
## Conversion to and from Stream/Sink
It is often convenient to encapsulate the reading and writing of bytes in a
[`Stream`] or [`Sink`] of data.
Tokio provides simple wrappers for converting [`AsyncRead`] to [`Stream`]
and vice-versa in the [tokio-util] crate, see [`ReaderStream`] and
[`StreamReader`].
There are also utility traits that abstract the asynchronous buffering
necessary to write your own adaptors for encoding and decoding bytes to/from
your structured data, allowing to transform something that implements
[`AsyncRead`]/[`AsyncWrite`] into a [`Stream`]/[`Sink`], see [`Decoder`] and
[`Encoder`] in the [tokio-util::codec] module.
[tokio-util]: https://docs.rs/tokio-util
[tokio-util::codec]: https://docs.rs/tokio-util/latest/tokio_util/codec/index.html
# Standard input and output
Tokio provides asynchronous APIs to standard [input], [output], and [error].
These APIs are very similar to the ones provided by `std`, but they also
implement [`AsyncRead`] and [`AsyncWrite`].
Note that the standard input / output APIs **must** be used from the
context of the Tokio runtime, as they require Tokio-specific features to
function. Calling these functions outside of a Tokio runtime will panic.
[input]: fn@stdin
[output]: fn@stdout
[error]: fn@stderr
# `std` re-exports
Additionally, [`Error`], [`ErrorKind`], [`Result`], and [`SeekFrom`] are
re-exported from `std::io` for ease of use.
[`AsyncRead`]: trait@AsyncRead
[`AsyncWrite`]: trait@AsyncWrite
[`AsyncReadExt`]: trait@AsyncReadExt
[`AsyncWriteExt`]: trait@AsyncWriteExt
["codec"]: https://docs.rs/tokio-util/latest/tokio_util/codec/index.html
[`Encoder`]: https://docs.rs/tokio-util/latest/tokio_util/codec/trait.Encoder.html
[`Decoder`]: https://docs.rs/tokio-util/latest/tokio_util/codec/trait.Decoder.html
[`ReaderStream`]: https://docs.rs/tokio-util/latest/tokio_util/io/struct.ReaderStream.html
[`StreamReader`]: https://docs.rs/tokio-util/latest/tokio_util/io/struct.StreamReader.html
[`Error`]: struct@Error
[`ErrorKind`]: enum@ErrorKind
[`Result`]: type@Result
[`Read`]: std::io::Read
[`SeekFrom`]: enum@SeekFrom
[`Sink`]: https://docs.rs/futures/0.3/futures/sink/trait.Sink.html
[`Stream`]: https://docs.rs/futures/0.3/futures/stream/trait.Stream.html
[`Write`]: std::io::Write
```rust
pub mod io { /* ... */ }
```
### Modules
## Module `bsd`
**Attributes:**
- `Other("#[<cfg>(all(any(docsrs, target_os = \"freebsd\"), feature = \"net\"))]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(all(target_os = \"freebsd\", feature = \"net\"))))]")`
- `Other("#[doc(cfg(all(target_os = \"freebsd\", feature = \"net\")))]")`
BSD-specific I/O types.
```rust
pub mod bsd { /* ... */ }
```
### Re-exports
#### Re-export `Aio`
```rust
pub use poll_aio::Aio;
```
#### Re-export `AioEvent`
```rust
pub use poll_aio::AioEvent;
```
#### Re-export `AioSource`
```rust
pub use poll_aio::AioSource;
```
## Module `unix`
**Attributes:**
- `Other("#[<cfg>(all(unix, feature = \"net\"))]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(all(unix, feature = \"net\"))))]")`
- `Other("#[doc(cfg(all(unix, feature = \"net\")))]")`
Asynchronous IO structures specific to Unix-like operating systems.
```rust
pub mod unix { /* ... */ }
```
### Re-exports
#### Re-export `AsyncFd`
```rust
pub use super::async_fd::AsyncFd;
```
#### Re-export `AsyncFdTryNewError`
```rust
pub use super::async_fd::AsyncFdTryNewError;
```
#### Re-export `AsyncFdReadyGuard`
```rust
pub use super::async_fd::AsyncFdReadyGuard;
```
#### Re-export `AsyncFdReadyMutGuard`
```rust
pub use super::async_fd::AsyncFdReadyMutGuard;
```
#### Re-export `TryIoError`
```rust
pub use super::async_fd::TryIoError;
```
### Re-exports
#### Re-export `AsyncBufRead`
```rust
pub use self::async_buf_read::AsyncBufRead;
```
#### Re-export `AsyncRead`
```rust
pub use self::async_read::AsyncRead;
```
#### Re-export `AsyncSeek`
```rust
pub use self::async_seek::AsyncSeek;
```
#### Re-export `AsyncWrite`
```rust
pub use self::async_write::AsyncWrite;
```
#### Re-export `ReadBuf`
```rust
pub use self::read_buf::ReadBuf;
```
#### Re-export `Error`
**Attributes:**
- `Other("#[doc(no_inline)]")`
```rust
pub use std::io::Error;
```
#### Re-export `ErrorKind`
**Attributes:**
- `Other("#[doc(no_inline)]")`
```rust
pub use std::io::ErrorKind;
```
#### Re-export `Result`
**Attributes:**
- `Other("#[doc(no_inline)]")`
```rust
pub use std::io::Result;
```
#### Re-export `SeekFrom`
**Attributes:**
- `Other("#[doc(no_inline)]")`
```rust
pub use std::io::SeekFrom;
```
#### Re-export `Interest`
**Attributes:**
- `Other("#[<cfg>(any(feature = \"net\",\nall(tokio_unstable, feature = \"io-uring\", feature = \"rt\", feature = \"fs\",\ntarget_os = \"linux\",)))]")`
- `Other("#[<cfg_attr>(docsrs,\ndoc(cfg(any(feature = \"net\",\nall(tokio_unstable, feature = \"io-uring\", feature = \"rt\", feature = \"fs\",\ntarget_os = \"linux\",)))))]")`
- `Other("#[doc(cfg(any(feature = \"net\",\nall(tokio_unstable, feature = \"io-uring\", feature = \"rt\", feature = \"fs\",\ntarget_os = \"linux\",))))]")`
```rust
pub use interest::Interest;
```
#### Re-export `Ready`
**Attributes:**
- `Other("#[<cfg>(any(feature = \"net\",\nall(tokio_unstable, feature = \"io-uring\", feature = \"rt\", feature = \"fs\",\ntarget_os = \"linux\",)))]")`
- `Other("#[<cfg_attr>(docsrs,\ndoc(cfg(any(feature = \"net\",\nall(tokio_unstable, feature = \"io-uring\", feature = \"rt\", feature = \"fs\",\ntarget_os = \"linux\",)))))]")`
- `Other("#[doc(cfg(any(feature = \"net\",\nall(tokio_unstable, feature = \"io-uring\", feature = \"rt\", feature = \"fs\",\ntarget_os = \"linux\",))))]")`
```rust
pub use ready::Ready;
```
#### Re-export `stderr`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-std\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-std\")))]")`
- `Other("#[doc(cfg(feature = \"io-std\"))]")`
```rust
pub use stderr::stderr;
```
#### Re-export `Stderr`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-std\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-std\")))]")`
- `Other("#[doc(cfg(feature = \"io-std\"))]")`
```rust
pub use stderr::Stderr;
```
#### Re-export `stdin`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-std\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-std\")))]")`
- `Other("#[doc(cfg(feature = \"io-std\"))]")`
```rust
pub use stdin::stdin;
```
#### Re-export `Stdin`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-std\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-std\")))]")`
- `Other("#[doc(cfg(feature = \"io-std\"))]")`
```rust
pub use stdin::Stdin;
```
#### Re-export `stdout`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-std\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-std\")))]")`
- `Other("#[doc(cfg(feature = \"io-std\"))]")`
```rust
pub use stdout::stdout;
```
#### Re-export `Stdout`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-std\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-std\")))]")`
- `Other("#[doc(cfg(feature = \"io-std\"))]")`
```rust
pub use stdout::Stdout;
```
#### Re-export `split`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use split::split;
```
#### Re-export `ReadHalf`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use split::ReadHalf;
```
#### Re-export `WriteHalf`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use split::WriteHalf;
```
#### Re-export `join`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use join::join;
```
#### Re-export `Join`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use join::Join;
```
#### Re-export `copy`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use util::copy;
```
#### Re-export `copy_bidirectional`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use util::copy_bidirectional;
```
#### Re-export `copy_bidirectional_with_sizes`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use util::copy_bidirectional_with_sizes;
```
#### Re-export `copy_buf`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use util::copy_buf;
```
#### Re-export `duplex`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use util::duplex;
```
#### Re-export `empty`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use util::empty;
```
#### Re-export `repeat`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use util::repeat;
```
#### Re-export `sink`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use util::sink;
```
#### Re-export `simplex`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use util::simplex;
```
#### Re-export `AsyncBufReadExt`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use util::AsyncBufReadExt;
```
#### Re-export `AsyncReadExt`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use util::AsyncReadExt;
```
#### Re-export `AsyncSeekExt`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use util::AsyncSeekExt;
```
#### Re-export `AsyncWriteExt`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use util::AsyncWriteExt;
```
#### Re-export `BufReader`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use util::BufReader;
```
#### Re-export `BufStream`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use util::BufStream;
```
#### Re-export `BufWriter`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use util::BufWriter;
```
#### Re-export `Chain`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use util::Chain;
```
#### Re-export `DuplexStream`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use util::DuplexStream;
```
#### Re-export `Empty`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use util::Empty;
```
#### Re-export `Lines`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use util::Lines;
```
#### Re-export `Repeat`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use util::Repeat;
```
#### Re-export `Sink`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use util::Sink;
```
#### Re-export `Split`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use util::Split;
```
#### Re-export `Take`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use util::Take;
```
#### Re-export `SimplexStream`
**Attributes:**
- `Other("#[<cfg>(feature = \"io-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"io-util\")))]")`
- `Other("#[doc(cfg(feature = \"io-util\"))]")`
```rust
pub use util::SimplexStream;
```
## Module `net`
**Attributes:**
- `Other("#[<cfg>(not(loom))]")`
TCP/UDP/Unix bindings for `tokio`.
This module contains the TCP/UDP/Unix networking types, similar to the standard
library, which can be used to implement networking protocols.
# Organization
* [`TcpListener`] and [`TcpStream`] provide functionality for communication over TCP
* [`UdpSocket`] provides functionality for communication over UDP
* [`UnixListener`] and [`UnixStream`] provide functionality for communication over a
Unix Domain Stream Socket **(available on Unix only)**
* [`UnixDatagram`] provides functionality for communication
over Unix Domain Datagram Socket **(available on Unix only)**
* [`tokio::net::unix::pipe`] for FIFO pipes **(available on Unix only)**
* [`tokio::net::windows::named_pipe`] for Named Pipes **(available on Windows only)**
For IO resources not available in `tokio::net`, you can use [`AsyncFd`].
[`TcpListener`]: TcpListener
[`TcpStream`]: TcpStream
[`UdpSocket`]: UdpSocket
[`UnixListener`]: UnixListener
[`UnixStream`]: UnixStream
[`UnixDatagram`]: UnixDatagram
[`tokio::net::unix::pipe`]: unix::pipe
[`tokio::net::windows::named_pipe`]: windows::named_pipe
[`AsyncFd`]: crate::io::unix::AsyncFd
```rust
pub mod net { /* ... */ }
```
### Modules
## Module `tcp`
**Attributes:**
- `Other("#[<cfg>(feature = \"net\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"net\")))]")`
- `Other("#[doc(cfg(feature = \"net\"))]")`
TCP utility types.
```rust
pub mod tcp { /* ... */ }
```
### Re-exports
#### Re-export `ReadHalf`
```rust
pub use split::ReadHalf;
```
#### Re-export `WriteHalf`
```rust
pub use split::WriteHalf;
```
#### Re-export `OwnedReadHalf`
```rust
pub use split_owned::OwnedReadHalf;
```
#### Re-export `OwnedWriteHalf`
```rust
pub use split_owned::OwnedWriteHalf;
```
#### Re-export `ReuniteError`
```rust
pub use split_owned::ReuniteError;
```
## Module `unix`
**Attributes:**
- `Other("#[<cfg>(all(unix, feature = \"net\"))]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(all(unix, feature = \"net\"))))]")`
- `Other("#[doc(cfg(all(unix, feature = \"net\")))]")`
Unix specific network types.
```rust
pub mod unix { /* ... */ }
```
### Modules
## Module `pipe`
Unix pipe types.
```rust
pub mod pipe { /* ... */ }
```
### Types
#### Struct `OpenOptions`
Options and flags which can be used to configure how a FIFO file is opened.
This builder allows configuring how to create a pipe end from a FIFO file.
Generally speaking, when using `OpenOptions`, you'll first call [`new`],
then chain calls to methods to set each option, then call either
[`open_receiver`] or [`open_sender`], passing the path of the FIFO file you
are trying to open. This will give you a [`io::Result`] with a pipe end
inside that you can further operate on.
[`new`]: OpenOptions::new
[`open_receiver`]: OpenOptions::open_receiver
[`open_sender`]: OpenOptions::open_sender
# Examples
Opening a pair of pipe ends from a FIFO file:
```no_run
use tokio::net::unix::pipe;
# use std::error::Error;
const FIFO_NAME: &str = "path/to/a/fifo";
# async fn dox() -> Result<(), Box<dyn Error>> {
let rx = pipe::OpenOptions::new().open_receiver(FIFO_NAME)?;
let tx = pipe::OpenOptions::new().open_sender(FIFO_NAME)?;
# Ok(())
# }
```
Opening a [`Sender`] on Linux when you are sure the file is a FIFO:
```ignore
use tokio::net::unix::pipe;
use nix::{unistd::mkfifo, sys::stat::Mode};
# use std::error::Error;
// Our program has exclusive access to this path.
const FIFO_NAME: &str = "path/to/a/new/fifo";
# async fn dox() -> Result<(), Box<dyn Error>> {
mkfifo(FIFO_NAME, Mode::S_IRWXU)?;
let tx = pipe::OpenOptions::new()
.read_write(true)
.unchecked(true)
.open_sender(FIFO_NAME)?;
# Ok(())
# }
```
```rust
pub struct OpenOptions {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub fn new() -> OpenOptions { /* ... */ }
```
Creates a blank new set of options ready for configuration.
- ```rust
pub fn read_write(self: &mut Self, value: bool) -> &mut Self { /* ... */ }
```
Sets the option for read-write access.
- ```rust
pub fn unchecked(self: &mut Self, value: bool) -> &mut Self { /* ... */ }
```
Sets the option to skip the check for FIFO file type.
- ```rust
pub fn open_receiver<P: AsRef<Path>>(self: &Self, path: P) -> io::Result<Receiver> { /* ... */ }
```
Creates a [`Receiver`] from a FIFO file with the options specified by `self`.
- ```rust
pub fn open_sender<P: AsRef<Path>>(self: &Self, path: P) -> io::Result<Sender> { /* ... */ }
```
Creates a [`Sender`] from a FIFO file with the options specified by `self`.
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Clone**
- ```rust
fn clone(self: &Self) -> OpenOptions { /* ... */ }
```
- **CloneToUninit**
- ```rust
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Default**
- ```rust
fn default() -> OpenOptions { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **ToOwned**
- ```rust
fn to_owned(self: &Self) -> T { /* ... */ }
```
- ```rust
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
```
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `Sender`
Writing end of a Unix pipe.
It can be constructed from a FIFO file with [`OpenOptions::open_sender`].
Opening a named pipe for writing involves a few steps.
Call to [`OpenOptions::open_sender`] might fail with an error indicating
different things:
* [`io::ErrorKind::NotFound`] - There is no file at the specified path.
* [`io::ErrorKind::InvalidInput`] - The file exists, but it is not a FIFO.
* [`ENXIO`] - The file is a FIFO, but no process has it open for reading.
Sleep for a while and try again.
* Other OS errors not specific to opening FIFO files.
Opening a `Sender` from a FIFO file should look like this:
```no_run
use tokio::net::unix::pipe;
use tokio::time::{self, Duration};
const FIFO_NAME: &str = "path/to/a/fifo";
# async fn dox() -> Result<(), Box<dyn std::error::Error>> {
// Wait for a reader to open the file.
let tx = loop {
match pipe::OpenOptions::new().open_sender(FIFO_NAME) {
Ok(tx) => break tx,
Err(e) if e.raw_os_error() == Some(libc::ENXIO) => {},
Err(e) => return Err(e.into()),
}
time::sleep(Duration::from_millis(50)).await;
};
# Ok(())
# }
```
On Linux, it is possible to create a `Sender` without waiting in a sleeping
loop. This is done by opening a named pipe in read-write access mode with
`OpenOptions::read_write`. This way, a `Sender` can at the same time hold
both a writing end and a reading end, and the latter allows to open a FIFO
without [`ENXIO`] error since the pipe is open for reading as well.
`Sender` cannot be used to read from a pipe, so in practice the read access
is only used when a FIFO is opened. However, using a `Sender` in read-write
mode **may lead to lost data**, because written data will be dropped by the
system as soon as all pipe ends are closed. To avoid lost data you have to
make sure that a reading end has been opened before dropping a `Sender`.
Note that using read-write access mode with FIFO files is not defined by
the POSIX standard and it is only guaranteed to work on Linux.
```ignore
use tokio::io::AsyncWriteExt;
use tokio::net::unix::pipe;
const FIFO_NAME: &str = "path/to/a/fifo";
# async fn dox() -> Result<(), Box<dyn std::error::Error>> {
let mut tx = pipe::OpenOptions::new()
.read_write(true)
.open_sender(FIFO_NAME)?;
// Asynchronously write to the pipe before a reader.
tx.write_all(b"hello world").await?;
# Ok(())
# }
```
[`ENXIO`]: https://docs.rs/libc/latest/libc/constant.ENXIO.html
```rust
pub struct Sender {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub fn from_file(file: File) -> io::Result<Sender> { /* ... */ }
```
Creates a new `Sender` from a [`File`].
- ```rust
pub fn from_owned_fd(owned_fd: OwnedFd) -> io::Result<Sender> { /* ... */ }
```
Creates a new `Sender` from an [`OwnedFd`].
- ```rust
pub fn from_file_unchecked(file: File) -> io::Result<Sender> { /* ... */ }
```
Creates a new `Sender` from a [`File`] without checking pipe properties.
- ```rust
pub fn from_owned_fd_unchecked(owned_fd: OwnedFd) -> io::Result<Sender> { /* ... */ }
```
Creates a new `Sender` from an [`OwnedFd`] without checking pipe properties.
- ```rust
pub async fn ready(self: &Self, interest: Interest) -> io::Result<Ready> { /* ... */ }
```
Waits for any of the requested ready states.
- ```rust
pub async fn writable(self: &Self) -> io::Result<()> { /* ... */ }
```
Waits for the pipe to become writable.
- ```rust
pub fn poll_write_ready(self: &Self, cx: &mut Context<''_>) -> Poll<io::Result<()>> { /* ... */ }
```
Polls for write readiness.
- ```rust
pub fn try_write(self: &Self, buf: &[u8]) -> io::Result<usize> { /* ... */ }
```
Tries to write a buffer to the pipe, returning how many bytes were
- ```rust
pub fn try_write_vectored(self: &Self, buf: &[io::IoSlice<''_>]) -> io::Result<usize> { /* ... */ }
```
Tries to write several buffers to the pipe, returning how many bytes
- ```rust
pub fn into_blocking_fd(self: Self) -> io::Result<OwnedFd> { /* ... */ }
```
Converts the pipe into an [`OwnedFd`] in blocking mode.
- ```rust
pub fn into_nonblocking_fd(self: Self) -> io::Result<OwnedFd> { /* ... */ }
```
Converts the pipe into an [`OwnedFd`] in nonblocking mode.
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **AsFd**
- ```rust
fn as_fd(self: &Self) -> BorrowedFd<''_> { /* ... */ }
```
- **AsRawFd**
- ```rust
fn as_raw_fd(self: &Self) -> RawFd { /* ... */ }
```
- **AsyncWrite**
- ```rust
fn poll_write(self: Pin<&mut Self>, cx: &mut Context<''_>, buf: &[u8]) -> Poll<io::Result<usize>> { /* ... */ }
```
- ```rust
fn poll_write_vectored(self: Pin<&mut Self>, cx: &mut Context<''_>, bufs: &[io::IoSlice<''_>]) -> Poll<io::Result<usize>> { /* ... */ }
```
- ```rust
fn is_write_vectored(self: &Self) -> bool { /* ... */ }
```
- ```rust
fn poll_flush(self: Pin<&mut Self>, _: &mut Context<''_>) -> Poll<io::Result<()>> { /* ... */ }
```
- ```rust
fn poll_shutdown(self: Pin<&mut Self>, _: &mut Context<''_>) -> Poll<io::Result<()>> { /* ... */ }
```
- **AsyncWriteExt**
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `Receiver`
Reading end of a Unix pipe.
It can be constructed from a FIFO file with [`OpenOptions::open_receiver`].
# Examples
Receiving messages from a named pipe in a loop:
```no_run
use tokio::net::unix::pipe;
use tokio::io::{self, AsyncReadExt};
const FIFO_NAME: &str = "path/to/a/fifo";
# async fn dox() -> Result<(), Box<dyn std::error::Error>> {
let mut rx = pipe::OpenOptions::new().open_receiver(FIFO_NAME)?;
loop {
let mut msg = vec![0; 256];
match rx.read_exact(&mut msg).await {
Ok(_) => {
/* handle the message */
}
Err(e) if e.kind() == io::ErrorKind::UnexpectedEof => {
// Writing end has been closed, we should reopen the pipe.
rx = pipe::OpenOptions::new().open_receiver(FIFO_NAME)?;
}
Err(e) => return Err(e.into()),
}
}
# }
```
On Linux, you can use a `Receiver` in read-write access mode to implement
resilient reading from a named pipe. Unlike `Receiver` opened in read-only
mode, read from a pipe in read-write mode will not fail with `UnexpectedEof`
when the writing end is closed. This way, a `Receiver` can asynchronously
wait for the next writer to open the pipe.
You should not use functions waiting for EOF such as [`read_to_end`] with
a `Receiver` in read-write access mode, since it **may wait forever**.
`Receiver` in this mode also holds an open writing end, which prevents
receiving EOF.
To set the read-write access mode you can use `OpenOptions::read_write`.
Note that using read-write access mode with FIFO files is not defined by
the POSIX standard and it is only guaranteed to work on Linux.
```ignore
use tokio::net::unix::pipe;
use tokio::io::AsyncReadExt;
# use std::error::Error;
const FIFO_NAME: &str = "path/to/a/fifo";
# async fn dox() -> Result<(), Box<dyn Error>> {
let mut rx = pipe::OpenOptions::new()
.read_write(true)
.open_receiver(FIFO_NAME)?;
loop {
let mut msg = vec![0; 256];
rx.read_exact(&mut msg).await?;
/* handle the message */
}
# }
```
[`read_to_end`]: crate::io::AsyncReadExt::read_to_end
```rust
pub struct Receiver {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub fn from_file(file: File) -> io::Result<Receiver> { /* ... */ }
```
Creates a new `Receiver` from a [`File`].
- ```rust
pub fn from_owned_fd(owned_fd: OwnedFd) -> io::Result<Receiver> { /* ... */ }
```
Creates a new `Receiver` from an [`OwnedFd`].
- ```rust
pub fn from_file_unchecked(file: File) -> io::Result<Receiver> { /* ... */ }
```
Creates a new `Receiver` from a [`File`] without checking pipe properties.
- ```rust
pub fn from_owned_fd_unchecked(owned_fd: OwnedFd) -> io::Result<Receiver> { /* ... */ }
```
Creates a new `Receiver` from an [`OwnedFd`] without checking pipe properties.
- ```rust
pub async fn ready(self: &Self, interest: Interest) -> io::Result<Ready> { /* ... */ }
```
Waits for any of the requested ready states.
- ```rust
pub async fn readable(self: &Self) -> io::Result<()> { /* ... */ }
```
Waits for the pipe to become readable.
- ```rust
pub fn poll_read_ready(self: &Self, cx: &mut Context<''_>) -> Poll<io::Result<()>> { /* ... */ }
```
Polls for read readiness.
- ```rust
pub fn try_read(self: &Self, buf: &mut [u8]) -> io::Result<usize> { /* ... */ }
```
Tries to read data from the pipe into the provided buffer, returning how
- ```rust
pub fn try_read_vectored(self: &Self, bufs: &mut [io::IoSliceMut<''_>]) -> io::Result<usize> { /* ... */ }
```
Tries to read data from the pipe into the provided buffers, returning
- ```rust
pub fn try_read_buf<B: BufMut>(self: &Self, buf: &mut B) -> io::Result<usize> { /* ... */ }
```
Tries to read data from the pipe into the provided buffer, advancing the
- ```rust
pub fn into_blocking_fd(self: Self) -> io::Result<OwnedFd> { /* ... */ }
```
Converts the pipe into an [`OwnedFd`] in blocking mode.
- ```rust
pub fn into_nonblocking_fd(self: Self) -> io::Result<OwnedFd> { /* ... */ }
```
Converts the pipe into an [`OwnedFd`] in nonblocking mode.
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **AsFd**
- ```rust
fn as_fd(self: &Self) -> BorrowedFd<''_> { /* ... */ }
```
- **AsRawFd**
- ```rust
fn as_raw_fd(self: &Self) -> RawFd { /* ... */ }
```
- **AsyncRead**
- ```rust
fn poll_read(self: Pin<&mut Self>, cx: &mut Context<''_>, buf: &mut ReadBuf<''_>) -> Poll<io::Result<()>> { /* ... */ }
```
- **AsyncReadExt**
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
### Functions
#### Function `pipe`
Creates a new anonymous Unix pipe.
This function will open a new pipe and associate both pipe ends with the default
event loop.
If you need to create a pipe for communication with a spawned process, you can
use [`Stdio::piped()`] instead.
[`Stdio::piped()`]: std::process::Stdio::piped
# Errors
If creating a pipe fails, this function will return with the related OS error.
# Examples
Create a pipe and pass the writing end to a spawned process.
```no_run
use tokio::net::unix::pipe;
use tokio::process::Command;
# use tokio::io::AsyncReadExt;
# use std::error::Error;
# async fn dox() -> Result<(), Box<dyn Error>> {
let (tx, mut rx) = pipe::pipe()?;
let mut buffer = String::new();
let status = Command::new("echo")
.arg("Hello, world!")
.stdout(tx.into_blocking_fd()?)
.status();
rx.read_to_string(&mut buffer).await?;
assert!(status.await?.success());
assert_eq!(buffer, "Hello, world!\n");
# Ok(())
# }
```
# Panics
This function panics if it is not called from within a runtime with
IO enabled.
The runtime is usually set implicitly when this function is called
from a future driven by a tokio runtime, otherwise runtime can be set
explicitly with [`Runtime::enter`](crate::runtime::Runtime::enter) function.
```rust
pub fn pipe() -> io::Result<(Sender, Receiver)> { /* ... */ }
```
### Types
#### Type Alias `uid_t`
**Attributes:**
- `Other("#[allow(non_camel_case_types)]")`
A type representing user ID.
```rust
pub type uid_t = u32;
```
#### Type Alias `gid_t`
**Attributes:**
- `Other("#[allow(non_camel_case_types)]")`
A type representing group ID.
```rust
pub type gid_t = u32;
```
#### Type Alias `pid_t`
**Attributes:**
- `Other("#[allow(non_camel_case_types)]")`
A type representing process and process group IDs.
```rust
pub type pid_t = i32;
```
### Re-exports
#### Re-export `ReadHalf`
```rust
pub use split::ReadHalf;
```
#### Re-export `WriteHalf`
```rust
pub use split::WriteHalf;
```
#### Re-export `OwnedReadHalf`
```rust
pub use split_owned::OwnedReadHalf;
```
#### Re-export `OwnedWriteHalf`
```rust
pub use split_owned::OwnedWriteHalf;
```
#### Re-export `ReuniteError`
```rust
pub use split_owned::ReuniteError;
```
#### Re-export `SocketAddr`
```rust
pub use socketaddr::SocketAddr;
```
#### Re-export `UCred`
```rust
pub use ucred::UCred;
```
## Module `windows`
**Attributes:**
- `Other("#[<cfg>(all(any(all(doc, docsrs), windows), feature = \"net\"))]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(all(windows, feature = \"net\"))))]")`
- `Other("#[doc(cfg(all(windows, feature = \"net\")))]")`
Windows specific network types.
```rust
pub mod windows { /* ... */ }
```
### Modules
## Module `named_pipe`
Tokio support for [Windows named pipes].
[Windows named pipes]: https://docs.microsoft.com/en-us/windows/win32/ipc/named-pipes
```rust
pub mod named_pipe { /* ... */ }
```
### Types
#### Struct `NamedPipeServer`
A [Windows named pipe] server.
Accepting client connections involves creating a server with
[`ServerOptions::create`] and waiting for clients to connect using
[`NamedPipeServer::connect`].
To avoid having clients sporadically fail with
[`std::io::ErrorKind::NotFound`] when they connect to a server, we must
ensure that at least one server instance is available at all times. This
means that the typical listen loop for a server is a bit involved, because
we have to ensure that we never drop a server accidentally while a client
might connect.
So a correctly implemented server looks like this:
```no_run
use std::io;
use tokio::net::windows::named_pipe::ServerOptions;
const PIPE_NAME: &str = r"\\.\pipe\named-pipe-idiomatic-server";
# #[tokio::main] async fn main() -> std::io::Result<()> {
// The first server needs to be constructed early so that clients can
// be correctly connected. Otherwise calling .wait will cause the client to
// error.
//
// Here we also make use of `first_pipe_instance`, which will ensure that
// there are no other servers up and running already.
let mut server = ServerOptions::new()
.first_pipe_instance(true)
.create(PIPE_NAME)?;
// Spawn the server loop.
let server = tokio::spawn(async move {
loop {
// Wait for a client to connect.
server.connect().await?;
let connected_client = server;
// Construct the next server to be connected before sending the one
// we already have of onto a task. This ensures that the server
// isn't closed (after it's done in the task) before a new one is
// available. Otherwise the client might error with
// `io::ErrorKind::NotFound`.
server = ServerOptions::new().create(PIPE_NAME)?;
let client = tokio::spawn(async move {
/* use the connected client */
# Ok::<_, std::io::Error>(())
});
# if true { break } // needed for type inference to work
}
Ok::<_, io::Error>(())
});
/* do something else not server related here */
# Ok(()) }
```
[Windows named pipe]: https://docs.microsoft.com/en-us/windows/win32/ipc/named-pipes
```rust
pub struct NamedPipeServer {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub unsafe fn from_raw_handle(handle: RawHandle) -> io::Result<Self> { /* ... */ }
```
Constructs a new named pipe server from the specified raw handle.
- ```rust
pub fn info(self: &Self) -> io::Result<PipeInfo> { /* ... */ }
```
Retrieves information about the named pipe the server is associated
- ```rust
pub async fn connect(self: &Self) -> io::Result<()> { /* ... */ }
```
Enables a named pipe server process to wait for a client process to
- ```rust
pub fn disconnect(self: &Self) -> io::Result<()> { /* ... */ }
```
Disconnects the server end of a named pipe instance from a client
- ```rust
pub async fn ready(self: &Self, interest: Interest) -> io::Result<Ready> { /* ... */ }
```
Waits for any of the requested ready states.
- ```rust
pub async fn readable(self: &Self) -> io::Result<()> { /* ... */ }
```
Waits for the pipe to become readable.
- ```rust
pub fn poll_read_ready(self: &Self, cx: &mut Context<''_>) -> Poll<io::Result<()>> { /* ... */ }
```
Polls for read readiness.
- ```rust
pub fn try_read(self: &Self, buf: &mut [u8]) -> io::Result<usize> { /* ... */ }
```
Tries to read data from the pipe into the provided buffer, returning how
- ```rust
pub fn try_read_vectored(self: &Self, bufs: &mut [io::IoSliceMut<''_>]) -> io::Result<usize> { /* ... */ }
```
Tries to read data from the pipe into the provided buffers, returning
- ```rust
pub fn try_read_buf<B: BufMut>(self: &Self, buf: &mut B) -> io::Result<usize> { /* ... */ }
```
Tries to read data from the stream into the provided buffer, advancing the
- ```rust
pub async fn writable(self: &Self) -> io::Result<()> { /* ... */ }
```
Waits for the pipe to become writable.
- ```rust
pub fn poll_write_ready(self: &Self, cx: &mut Context<''_>) -> Poll<io::Result<()>> { /* ... */ }
```
Polls for write readiness.
- ```rust
pub fn try_write(self: &Self, buf: &[u8]) -> io::Result<usize> { /* ... */ }
```
Tries to write a buffer to the pipe, returning how many bytes were
- ```rust
pub fn try_write_vectored(self: &Self, buf: &[io::IoSlice<''_>]) -> io::Result<usize> { /* ... */ }
```
Tries to write several buffers to the pipe, returning how many bytes
- ```rust
pub fn try_io<R, /* synthetic */ impl FnOnce() -> io::Result<R>: FnOnce() -> io::Result<R>>(self: &Self, interest: Interest, f: impl FnOnce() -> io::Result<R>) -> io::Result<R> { /* ... */ }
```
Tries to read or write from the pipe using a user-provided IO operation.
- ```rust
pub async fn async_io<R, /* synthetic */ impl FnMut() -> io::Result<R>: FnMut() -> io::Result<R>>(self: &Self, interest: Interest, f: impl FnMut() -> io::Result<R>) -> io::Result<R> { /* ... */ }
```
Reads or writes from the pipe using a user-provided IO operation.
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **AsHandle**
- ```rust
fn as_handle(self: &Self) -> BorrowedHandle<''_> { /* ... */ }
```
- **AsRawHandle**
- ```rust
fn as_raw_handle(self: &Self) -> RawHandle { /* ... */ }
```
- **AsyncRead**
- ```rust
fn poll_read(self: Pin<&mut Self>, cx: &mut Context<''_>, buf: &mut ReadBuf<''_>) -> Poll<io::Result<()>> { /* ... */ }
```
- **AsyncReadExt**
- **AsyncWrite**
- ```rust
fn poll_write(self: Pin<&mut Self>, cx: &mut Context<''_>, buf: &[u8]) -> Poll<io::Result<usize>> { /* ... */ }
```
- ```rust
fn poll_write_vectored(self: Pin<&mut Self>, cx: &mut Context<''_>, bufs: &[io::IoSlice<''_>]) -> Poll<io::Result<usize>> { /* ... */ }
```
- ```rust
fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<''_>) -> Poll<io::Result<()>> { /* ... */ }
```
- ```rust
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<''_>) -> Poll<io::Result<()>> { /* ... */ }
```
- **AsyncWriteExt**
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `NamedPipeClient`
A [Windows named pipe] client.
Constructed using [`ClientOptions::open`].
Connecting a client correctly involves a few steps. When connecting through
[`ClientOptions::open`], it might error indicating one of two things:
* [`std::io::ErrorKind::NotFound`] - There is no server available.
* [`ERROR_PIPE_BUSY`] - There is a server available, but it is busy. Sleep
for a while and try again.
So a correctly implemented client looks like this:
```no_run
use std::time::Duration;
use tokio::net::windows::named_pipe::ClientOptions;
use tokio::time;
use windows_sys::Win32::Foundation::ERROR_PIPE_BUSY;
const PIPE_NAME: &str = r"\\.\pipe\named-pipe-idiomatic-client";
# #[tokio::main] async fn main() -> std::io::Result<()> {
let client = loop {
match ClientOptions::new().open(PIPE_NAME) {
Ok(client) => break client,
Err(e) if e.raw_os_error() == Some(ERROR_PIPE_BUSY as i32) => (),
Err(e) => return Err(e),
}
time::sleep(Duration::from_millis(50)).await;
};
/* use the connected client */
# Ok(()) }
```
[`ERROR_PIPE_BUSY`]: https://docs.rs/windows-sys/latest/windows_sys/Win32/Foundation/constant.ERROR_PIPE_BUSY.html
[Windows named pipe]: https://docs.microsoft.com/en-us/windows/win32/ipc/named-pipes
```rust
pub struct NamedPipeClient {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub unsafe fn from_raw_handle(handle: RawHandle) -> io::Result<Self> { /* ... */ }
```
Constructs a new named pipe client from the specified raw handle.
- ```rust
pub fn info(self: &Self) -> io::Result<PipeInfo> { /* ... */ }
```
Retrieves information about the named pipe the client is associated
- ```rust
pub async fn ready(self: &Self, interest: Interest) -> io::Result<Ready> { /* ... */ }
```
Waits for any of the requested ready states.
- ```rust
pub async fn readable(self: &Self) -> io::Result<()> { /* ... */ }
```
Waits for the pipe to become readable.
- ```rust
pub fn poll_read_ready(self: &Self, cx: &mut Context<''_>) -> Poll<io::Result<()>> { /* ... */ }
```
Polls for read readiness.
- ```rust
pub fn try_read(self: &Self, buf: &mut [u8]) -> io::Result<usize> { /* ... */ }
```
Tries to read data from the pipe into the provided buffer, returning how
- ```rust
pub fn try_read_vectored(self: &Self, bufs: &mut [io::IoSliceMut<''_>]) -> io::Result<usize> { /* ... */ }
```
Tries to read data from the pipe into the provided buffers, returning
- ```rust
pub fn try_read_buf<B: BufMut>(self: &Self, buf: &mut B) -> io::Result<usize> { /* ... */ }
```
Tries to read data from the stream into the provided buffer, advancing the
- ```rust
pub async fn writable(self: &Self) -> io::Result<()> { /* ... */ }
```
Waits for the pipe to become writable.
- ```rust
pub fn poll_write_ready(self: &Self, cx: &mut Context<''_>) -> Poll<io::Result<()>> { /* ... */ }
```
Polls for write readiness.
- ```rust
pub fn try_write(self: &Self, buf: &[u8]) -> io::Result<usize> { /* ... */ }
```
Tries to write a buffer to the pipe, returning how many bytes were
- ```rust
pub fn try_write_vectored(self: &Self, buf: &[io::IoSlice<''_>]) -> io::Result<usize> { /* ... */ }
```
Tries to write several buffers to the pipe, returning how many bytes
- ```rust
pub fn try_io<R, /* synthetic */ impl FnOnce() -> io::Result<R>: FnOnce() -> io::Result<R>>(self: &Self, interest: Interest, f: impl FnOnce() -> io::Result<R>) -> io::Result<R> { /* ... */ }
```
Tries to read or write from the pipe using a user-provided IO operation.
- ```rust
pub async fn async_io<R, /* synthetic */ impl FnMut() -> io::Result<R>: FnMut() -> io::Result<R>>(self: &Self, interest: Interest, f: impl FnMut() -> io::Result<R>) -> io::Result<R> { /* ... */ }
```
Reads or writes from the pipe using a user-provided IO operation.
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **AsHandle**
- ```rust
fn as_handle(self: &Self) -> BorrowedHandle<''_> { /* ... */ }
```
- **AsRawHandle**
- ```rust
fn as_raw_handle(self: &Self) -> RawHandle { /* ... */ }
```
- **AsyncRead**
- ```rust
fn poll_read(self: Pin<&mut Self>, cx: &mut Context<''_>, buf: &mut ReadBuf<''_>) -> Poll<io::Result<()>> { /* ... */ }
```
- **AsyncReadExt**
- **AsyncWrite**
- ```rust
fn poll_write(self: Pin<&mut Self>, cx: &mut Context<''_>, buf: &[u8]) -> Poll<io::Result<usize>> { /* ... */ }
```
- ```rust
fn poll_write_vectored(self: Pin<&mut Self>, cx: &mut Context<''_>, bufs: &[io::IoSlice<''_>]) -> Poll<io::Result<usize>> { /* ... */ }
```
- ```rust
fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<''_>) -> Poll<io::Result<()>> { /* ... */ }
```
- ```rust
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<''_>) -> Poll<io::Result<()>> { /* ... */ }
```
- **AsyncWriteExt**
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `ServerOptions`
A builder structure for construct a named pipe with named pipe-specific
options. This is required to use for named pipe servers who wants to modify
pipe-related options.
See [`ServerOptions::create`].
```rust
pub struct ServerOptions {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub fn new() -> ServerOptions { /* ... */ }
```
Creates a new named pipe builder with the default settings.
- ```rust
pub fn pipe_mode(self: &mut Self, pipe_mode: PipeMode) -> &mut Self { /* ... */ }
```
The pipe mode.
- ```rust
pub fn access_inbound(self: &mut Self, allowed: bool) -> &mut Self { /* ... */ }
```
The flow of data in the pipe goes from client to server only.
- ```rust
pub fn access_outbound(self: &mut Self, allowed: bool) -> &mut Self { /* ... */ }
```
The flow of data in the pipe goes from server to client only.
- ```rust
pub fn first_pipe_instance(self: &mut Self, first: bool) -> &mut Self { /* ... */ }
```
If you attempt to create multiple instances of a pipe with this flag
- ```rust
pub fn write_dac(self: &mut Self, requested: bool) -> &mut Self { /* ... */ }
```
Requests permission to modify the pipe's discretionary access control list.
- ```rust
pub fn write_owner(self: &mut Self, requested: bool) -> &mut Self { /* ... */ }
```
Requests permission to modify the pipe's owner.
- ```rust
pub fn access_system_security(self: &mut Self, requested: bool) -> &mut Self { /* ... */ }
```
Requests permission to modify the pipe's system access control list.
- ```rust
pub fn reject_remote_clients(self: &mut Self, reject: bool) -> &mut Self { /* ... */ }
```
Indicates whether this server can accept remote clients or not. Remote
- ```rust
pub fn max_instances(self: &mut Self, instances: usize) -> &mut Self { /* ... */ }
```
The maximum number of instances that can be created for this pipe. The
- ```rust
pub fn out_buffer_size(self: &mut Self, buffer: u32) -> &mut Self { /* ... */ }
```
The number of bytes to reserve for the output buffer.
- ```rust
pub fn in_buffer_size(self: &mut Self, buffer: u32) -> &mut Self { /* ... */ }
```
The number of bytes to reserve for the input buffer.
- ```rust
pub fn create</* synthetic */ impl AsRef<OsStr>: AsRef<OsStr>>(self: &Self, addr: impl AsRef<OsStr>) -> io::Result<NamedPipeServer> { /* ... */ }
```
Creates the named pipe identified by `addr` for use as a server.
- ```rust
pub unsafe fn create_with_security_attributes_raw</* synthetic */ impl AsRef<OsStr>: AsRef<OsStr>>(self: &Self, addr: impl AsRef<OsStr>, attrs: *mut c_void) -> io::Result<NamedPipeServer> { /* ... */ }
```
Creates the named pipe identified by `addr` for use as a server.
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Clone**
- ```rust
fn clone(self: &Self) -> ServerOptions { /* ... */ }
```
- **CloneToUninit**
- ```rust
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **ToOwned**
- ```rust
fn to_owned(self: &Self) -> T { /* ... */ }
```
- ```rust
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
```
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `ClientOptions`
A builder suitable for building and interacting with named pipes from the
client side.
See [`ClientOptions::open`].
```rust
pub struct ClientOptions {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub fn new() -> Self { /* ... */ }
```
Creates a new named pipe builder with the default settings.
- ```rust
pub fn read(self: &mut Self, allowed: bool) -> &mut Self { /* ... */ }
```
If the client supports reading data. This is enabled by default.
- ```rust
pub fn write(self: &mut Self, allowed: bool) -> &mut Self { /* ... */ }
```
If the created pipe supports writing data. This is enabled by default.
- ```rust
pub fn security_qos_flags(self: &mut Self, flags: u32) -> &mut Self { /* ... */ }
```
Sets qos flags which are combined with other flags and attributes in the
- ```rust
pub fn pipe_mode(self: &mut Self, pipe_mode: PipeMode) -> &mut Self { /* ... */ }
```
The pipe mode.
- ```rust
pub fn open</* synthetic */ impl AsRef<OsStr>: AsRef<OsStr>>(self: &Self, addr: impl AsRef<OsStr>) -> io::Result<NamedPipeClient> { /* ... */ }
```
Opens the named pipe identified by `addr`.
- ```rust
pub unsafe fn open_with_security_attributes_raw</* synthetic */ impl AsRef<OsStr>: AsRef<OsStr>>(self: &Self, addr: impl AsRef<OsStr>, attrs: *mut c_void) -> io::Result<NamedPipeClient> { /* ... */ }
```
Opens the named pipe identified by `addr`.
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Clone**
- ```rust
fn clone(self: &Self) -> ClientOptions { /* ... */ }
```
- **CloneToUninit**
- ```rust
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **ToOwned**
- ```rust
fn to_owned(self: &Self) -> T { /* ... */ }
```
- ```rust
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
```
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Enum `PipeMode`
**Attributes:**
- `NonExhaustive`
The pipe mode of a named pipe.
Set through [`ServerOptions::pipe_mode`].
```rust
pub enum PipeMode {
Byte,
Message,
}
```
##### Variants
###### `Byte`
Data is written to the pipe as a stream of bytes. The pipe does not
distinguish bytes written during different write operations.
Corresponds to [`PIPE_TYPE_BYTE`].
[`PIPE_TYPE_BYTE`]: https://docs.rs/windows-sys/latest/windows_sys/Win32/System/Pipes/constant.PIPE_TYPE_BYTE.html
###### `Message`
Data is written to the pipe as a stream of messages. The pipe treats the
bytes written during each write operation as a message unit. Any reading
on a named pipe returns [`ERROR_MORE_DATA`] when a message is not read
completely.
Corresponds to [`PIPE_TYPE_MESSAGE`].
[`ERROR_MORE_DATA`]: https://docs.rs/windows-sys/latest/windows_sys/Win32/Foundation/constant.ERROR_MORE_DATA.html
[`PIPE_TYPE_MESSAGE`]: https://docs.rs/windows-sys/latest/windows_sys/Win32/System/Pipes/constant.PIPE_TYPE_MESSAGE.html
##### Implementations
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Clone**
- ```rust
fn clone(self: &Self) -> PipeMode { /* ... */ }
```
- **CloneToUninit**
- ```rust
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
```
- **Copy**
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Eq**
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Hash**
- ```rust
fn hash<__H: $crate::hash::Hasher>(self: &Self, state: &mut __H) { /* ... */ }
```
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **PartialEq**
- ```rust
fn eq(self: &Self, other: &PipeMode) -> bool { /* ... */ }
```
- **RefUnwindSafe**
- **Send**
- **StructuralPartialEq**
- **Sync**
- **ToOwned**
- ```rust
fn to_owned(self: &Self) -> T { /* ... */ }
```
- ```rust
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
```
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Enum `PipeEnd`
**Attributes:**
- `NonExhaustive`
Indicates the end of a named pipe.
```rust
pub enum PipeEnd {
Client,
Server,
}
```
##### Variants
###### `Client`
The named pipe refers to the client end of a named pipe instance.
Corresponds to [`PIPE_CLIENT_END`].
[`PIPE_CLIENT_END`]: https://docs.rs/windows-sys/latest/windows_sys/Win32/System/Pipes/constant.PIPE_CLIENT_END.html
###### `Server`
The named pipe refers to the server end of a named pipe instance.
Corresponds to [`PIPE_SERVER_END`].
[`PIPE_SERVER_END`]: https://docs.rs/windows-sys/latest/windows_sys/Win32/System/Pipes/constant.PIPE_SERVER_END.html
##### Implementations
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Clone**
- ```rust
fn clone(self: &Self) -> PipeEnd { /* ... */ }
```
- **CloneToUninit**
- ```rust
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
```
- **Copy**
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Eq**
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Hash**
- ```rust
fn hash<__H: $crate::hash::Hasher>(self: &Self, state: &mut __H) { /* ... */ }
```
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **PartialEq**
- ```rust
fn eq(self: &Self, other: &PipeEnd) -> bool { /* ... */ }
```
- **RefUnwindSafe**
- **Send**
- **StructuralPartialEq**
- **Sync**
- **ToOwned**
- ```rust
fn to_owned(self: &Self) -> T { /* ... */ }
```
- ```rust
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
```
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `PipeInfo`
**Attributes:**
- `NonExhaustive`
Information about a named pipe.
Constructed through [`NamedPipeServer::info`] or [`NamedPipeClient::info`].
```rust
pub struct PipeInfo {
pub mode: PipeMode,
pub end: PipeEnd,
pub max_instances: u32,
pub out_buffer_size: u32,
pub in_buffer_size: u32,
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| `mode` | `PipeMode` | Indicates the mode of a named pipe. |
| `end` | `PipeEnd` | Indicates the end of a named pipe. |
| `max_instances` | `u32` | The maximum number of instances that can be created for this pipe. |
| `out_buffer_size` | `u32` | The number of bytes to reserve for the output buffer. |
| `in_buffer_size` | `u32` | The number of bytes to reserve for the input buffer. |
##### Implementations
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Clone**
- ```rust
fn clone(self: &Self) -> PipeInfo { /* ... */ }
```
- **CloneToUninit**
- ```rust
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **ToOwned**
- ```rust
fn to_owned(self: &Self) -> T { /* ... */ }
```
- ```rust
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
```
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
### Re-exports
#### Re-export `ToSocketAddrs`
```rust
pub use addr::ToSocketAddrs;
```
#### Re-export `lookup_host`
**Attributes:**
- `Other("#[<cfg>(feature = \"net\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"net\")))]")`
- `Other("#[doc(cfg(feature = \"net\"))]")`
```rust
pub use lookup_host::lookup_host;
```
#### Re-export `TcpListener`
**Attributes:**
- `Other("#[<cfg>(feature = \"net\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"net\")))]")`
- `Other("#[doc(cfg(feature = \"net\"))]")`
```rust
pub use tcp::listener::TcpListener;
```
#### Re-export `TcpStream`
**Attributes:**
- `Other("#[<cfg>(feature = \"net\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"net\")))]")`
- `Other("#[doc(cfg(feature = \"net\"))]")`
```rust
pub use tcp::stream::TcpStream;
```
#### Re-export `TcpSocket`
**Attributes:**
- `Other("#[<cfg>(not(target_os = \"wasi\"))]")`
```rust
pub use tcp::socket::TcpSocket;
```
#### Re-export `UdpSocket`
**Attributes:**
- `Other("#[<cfg>(not(target_os = \"wasi\"))]")`
- `Other("#[doc(inline)]")`
```rust
pub use udp::UdpSocket;
```
#### Re-export `UnixDatagram`
**Attributes:**
- `Other("#[<cfg>(all(unix, feature = \"net\"))]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(all(unix, feature = \"net\"))))]")`
- `Other("#[doc(cfg(all(unix, feature = \"net\")))]")`
```rust
pub use unix::datagram::socket::UnixDatagram;
```
#### Re-export `UnixListener`
**Attributes:**
- `Other("#[<cfg>(all(unix, feature = \"net\"))]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(all(unix, feature = \"net\"))))]")`
- `Other("#[doc(cfg(all(unix, feature = \"net\")))]")`
```rust
pub use unix::listener::UnixListener;
```
#### Re-export `UnixStream`
**Attributes:**
- `Other("#[<cfg>(all(unix, feature = \"net\"))]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(all(unix, feature = \"net\"))))]")`
- `Other("#[doc(cfg(all(unix, feature = \"net\")))]")`
```rust
pub use unix::stream::UnixStream;
```
#### Re-export `UnixSocket`
**Attributes:**
- `Other("#[<cfg>(all(unix, feature = \"net\"))]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(all(unix, feature = \"net\"))))]")`
- `Other("#[doc(cfg(all(unix, feature = \"net\")))]")`
```rust
pub use unix::socket::UnixSocket;
```
## Module `process`
**Attributes:**
- `Other("#[<cfg>(feature = \"process\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"process\")))]")`
- `Other("#[doc(cfg(feature = \"process\"))]")`
- `Other("#[<cfg>(not(loom))]")`
- `Other("#[<cfg>(not(target_os = \"wasi\"))]")`
An implementation of asynchronous process management for Tokio.
This module provides a [`Command`] struct that imitates the interface of the
[`std::process::Command`] type in the standard library, but provides asynchronous versions of
functions that create processes. These functions (`spawn`, `status`, `output` and their
variants) return "future aware" types that interoperate with Tokio. The asynchronous process
support is provided through signal handling on Unix and system APIs on Windows.
[`std::process::Command`]: std::process::Command
# Examples
Here's an example program which will spawn `echo hello world` and then wait
for it complete.
```no_run
use tokio::process::Command;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// The usage is similar as with the standard library's `Command` type
let mut child = Command::new("echo")
.arg("hello")
.arg("world")
.spawn()
.expect("failed to spawn");
// Await until the command completes
let status = child.wait().await?;
println!("the command exited with: {}", status);
Ok(())
}
```
Next, let's take a look at an example where we not only spawn `echo hello
world` but we also capture its output.
```no_run
use tokio::process::Command;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Like above, but use `output` which returns a future instead of
// immediately returning the `Child`.
let output = Command::new("echo").arg("hello").arg("world")
.output();
let output = output.await?;
assert!(output.status.success());
assert_eq!(output.stdout, b"hello world\n");
Ok(())
}
```
We can also read input line by line.
```no_run
use tokio::io::{BufReader, AsyncBufReadExt};
use tokio::process::Command;
use std::process::Stdio;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut cmd = Command::new("cat");
// Specify that we want the command's standard output piped back to us.
// By default, standard input/output/error will be inherited from the
// current process (for example, this means that standard input will
// come from the keyboard and standard output/error will go directly to
// the terminal if this process is invoked from the command line).
cmd.stdout(Stdio::piped());
let mut child = cmd.spawn()
.expect("failed to spawn command");
let stdout = child.stdout.take()
.expect("child did not have a handle to stdout");
let mut reader = BufReader::new(stdout).lines();
// Ensure the child process is spawned in the runtime so it can
// make progress on its own while we await for any output.
tokio::spawn(async move {
let status = child.wait().await
.expect("child process encountered an error");
println!("child status was: {}", status);
});
while let Some(line) = reader.next_line().await? {
println!("Line: {}", line);
}
Ok(())
}
```
Here is another example using `sort` writing into the child process
standard input, capturing the output of the sorted text.
```no_run
use tokio::io::AsyncWriteExt;
use tokio::process::Command;
use std::process::Stdio;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut cmd = Command::new("sort");
// Specifying that we want pipe both the output and the input.
// Similarly to capturing the output, by configuring the pipe
// to stdin it can now be used as an asynchronous writer.
cmd.stdout(Stdio::piped());
cmd.stdin(Stdio::piped());
let mut child = cmd.spawn().expect("failed to spawn command");
// These are the animals we want to sort
let animals: &[&str] = &["dog", "bird", "frog", "cat", "fish"];
let mut stdin = child
.stdin
.take()
.expect("child did not have a handle to stdin");
// Write our animals to the child process
// Note that the behavior of `sort` is to buffer _all input_ before writing any output.
// In the general sense, it is recommended to write to the child in a separate task as
// awaiting its exit (or output) to avoid deadlocks (for example, the child tries to write
// some output but gets stuck waiting on the parent to read from it, meanwhile the parent
// is stuck waiting to write its input completely before reading the output).
stdin
.write(animals.join("\n").as_bytes())
.await
.expect("could not write to stdin");
// We drop the handle here which signals EOF to the child process.
// This tells the child process that it there is no more data on the pipe.
drop(stdin);
let op = child.wait_with_output().await?;
// Results should come back in sorted order
assert_eq!(op.stdout, "bird\ncat\ndog\nfish\nfrog\n".as_bytes());
Ok(())
}
```
With some coordination, we can also pipe the output of one command into
another.
```no_run
use tokio::join;
use tokio::process::Command;
use std::process::Stdio;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut echo = Command::new("echo")
.arg("hello world!")
.stdout(Stdio::piped())
.spawn()
.expect("failed to spawn echo");
let tr_stdin: Stdio = echo
.stdout
.take()
.unwrap()
.try_into()
.expect("failed to convert to Stdio");
let tr = Command::new("tr")
.arg("a-z")
.arg("A-Z")
.stdin(tr_stdin)
.stdout(Stdio::piped())
.spawn()
.expect("failed to spawn tr");
let (echo_result, tr_output) = join!(echo.wait(), tr.wait_with_output());
assert!(echo_result.unwrap().success());
let tr_output = tr_output.expect("failed to await tr");
assert!(tr_output.status.success());
assert_eq!(tr_output.stdout, b"HELLO WORLD!\n");
Ok(())
}
```
# Caveats
## Dropping/Cancellation
Similar to the behavior to the standard library, and unlike the futures
paradigm of dropping-implies-cancellation, a spawned process will, by
default, continue to execute even after the `Child` handle has been dropped.
The [`Command::kill_on_drop`] method can be used to modify this behavior
and kill the child process if the `Child` wrapper is dropped before it
has exited.
## Unix Processes
On Unix platforms processes must be "reaped" by their parent process after
they have exited in order to release all OS resources. A child process which
has exited, but has not yet been reaped by its parent is considered a "zombie"
process. Such processes continue to count against limits imposed by the system,
and having too many zombie processes present can prevent additional processes
from being spawned.
The tokio runtime will, on a best-effort basis, attempt to reap and clean up
any process which it has spawned. No additional guarantees are made with regard to
how quickly or how often this procedure will take place.
It is recommended to avoid dropping a [`Child`] process handle before it has been
fully `await`ed if stricter cleanup guarantees are required.
[`Command`]: crate::process::Command
[`Command::kill_on_drop`]: crate::process::Command::kill_on_drop
[`Child`]: crate::process::Child
```rust
pub mod process { /* ... */ }
```
### Types
#### Struct `Command`
This structure mimics the API of [`std::process::Command`] found in the standard library, but
replaces functions that create a process with an asynchronous variant. The main provided
asynchronous functions are [spawn](Command::spawn), [status](Command::status), and
[output](Command::output).
`Command` uses asynchronous versions of some `std` types (for example [`Child`]).
[`std::process::Command`]: std::process::Command
[`Child`]: struct@Child
```rust
pub struct Command {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub fn new<S: AsRef<OsStr>>(program: S) -> Command { /* ... */ }
```
Constructs a new `Command` for launching the program at
- ```rust
pub fn as_std(self: &Self) -> &StdCommand { /* ... */ }
```
Cheaply convert to a `&std::process::Command` for places where the type from the standard
- ```rust
pub fn as_std_mut(self: &mut Self) -> &mut StdCommand { /* ... */ }
```
Cheaply convert to a `&mut std::process::Command` for places where the type from the
- ```rust
pub fn into_std(self: Self) -> StdCommand { /* ... */ }
```
Cheaply convert into a `std::process::Command`.
- ```rust
pub fn arg<S: AsRef<OsStr>>(self: &mut Self, arg: S) -> &mut Command { /* ... */ }
```
Adds an argument to pass to the program.
- ```rust
pub fn args<I, S>(self: &mut Self, args: I) -> &mut Command
where
I: IntoIterator<Item = S>,
S: AsRef<OsStr> { /* ... */ }
```
Adds multiple arguments to pass to the program.
- ```rust
pub fn raw_arg<S: AsRef<OsStr>>(self: &mut Self, text_to_append_as_is: S) -> &mut Command { /* ... */ }
```
Append literal text to the command line without any quoting or escaping.
- ```rust
pub fn env<K, V>(self: &mut Self, key: K, val: V) -> &mut Command
where
K: AsRef<OsStr>,
V: AsRef<OsStr> { /* ... */ }
```
Inserts or updates an environment variable mapping.
- ```rust
pub fn envs<I, K, V>(self: &mut Self, vars: I) -> &mut Command
where
I: IntoIterator<Item = (K, V)>,
K: AsRef<OsStr>,
V: AsRef<OsStr> { /* ... */ }
```
Adds or updates multiple environment variable mappings.
- ```rust
pub fn env_remove<K: AsRef<OsStr>>(self: &mut Self, key: K) -> &mut Command { /* ... */ }
```
Removes an environment variable mapping.
- ```rust
pub fn env_clear(self: &mut Self) -> &mut Command { /* ... */ }
```
Clears the entire environment map for the child process.
- ```rust
pub fn current_dir<P: AsRef<Path>>(self: &mut Self, dir: P) -> &mut Command { /* ... */ }
```
Sets the working directory for the child process.
- ```rust
pub fn stdin<T: Into<Stdio>>(self: &mut Self, cfg: T) -> &mut Command { /* ... */ }
```
Sets configuration for the child process's standard input (stdin) handle.
- ```rust
pub fn stdout<T: Into<Stdio>>(self: &mut Self, cfg: T) -> &mut Command { /* ... */ }
```
Sets configuration for the child process's standard output (stdout) handle.
- ```rust
pub fn stderr<T: Into<Stdio>>(self: &mut Self, cfg: T) -> &mut Command { /* ... */ }
```
Sets configuration for the child process's standard error (stderr) handle.
- ```rust
pub fn kill_on_drop(self: &mut Self, kill_on_drop: bool) -> &mut Command { /* ... */ }
```
Controls whether a `kill` operation should be invoked on a spawned child
- ```rust
pub fn creation_flags(self: &mut Self, flags: u32) -> &mut Command { /* ... */ }
```
Sets the [process creation flags][1] to be passed to `CreateProcess`.
- ```rust
pub fn uid(self: &mut Self, id: u32) -> &mut Command { /* ... */ }
```
Sets the child process's user ID. This translates to a
- ```rust
pub fn gid(self: &mut Self, id: u32) -> &mut Command { /* ... */ }
```
Similar to `uid` but sets the group ID of the child process. This has
- ```rust
pub fn arg0<S>(self: &mut Self, arg: S) -> &mut Command
where
S: AsRef<OsStr> { /* ... */ }
```
Sets executable argument.
- ```rust
pub unsafe fn pre_exec<F>(self: &mut Self, f: F) -> &mut Command
where
F: FnMut() -> io::Result<()> + Send + Sync + ''static { /* ... */ }
```
Schedules a closure to be run just before the `exec` function is
- ```rust
pub fn process_group(self: &mut Self, pgroup: i32) -> &mut Command { /* ... */ }
```
Sets the process group ID (PGID) of the child process. Equivalent to a
- ```rust
pub fn spawn(self: &mut Self) -> io::Result<Child> { /* ... */ }
```
Executes the command as a child process, returning a handle to it.
- ```rust
pub fn spawn_with</* synthetic */ impl FnOnce(&mut StdCommand) -> io::Result<StdChild>: FnOnce(&mut StdCommand) -> io::Result<StdChild>>(self: &mut Self, with: impl FnOnce(&mut StdCommand) -> io::Result<StdChild>) -> io::Result<Child> { /* ... */ }
```
Executes the command as a child process with a custom spawning function,
- ```rust
pub fn status(self: &mut Self) -> impl Future<Output = io::Result<ExitStatus>> { /* ... */ }
```
Executes the command as a child process, waiting for it to finish and
- ```rust
pub fn output(self: &mut Self) -> impl Future<Output = io::Result<Output>> { /* ... */ }
```
Executes the command as a child process, waiting for it to finish and
- ```rust
pub fn get_kill_on_drop(self: &Self) -> bool { /* ... */ }
```
Returns the boolean value that was previously set by [`Command::kill_on_drop`].
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- ```rust
fn from(std: StdCommand) -> Command { /* ... */ }
```
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `Child`
Representation of a child process spawned onto an event loop.
# Caveats
Similar to the behavior to the standard library, and unlike the futures
paradigm of dropping-implies-cancellation, a spawned process will, by
default, continue to execute even after the `Child` handle has been dropped.
The `Command::kill_on_drop` method can be used to modify this behavior
and kill the child process if the `Child` wrapper is dropped before it
has exited.
```rust
pub struct Child {
pub stdin: Option<ChildStdin>,
pub stdout: Option<ChildStdout>,
pub stderr: Option<ChildStderr>,
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| `stdin` | `Option<ChildStdin>` | The handle for writing to the child's standard input (stdin), if it has<br>been captured. To avoid partially moving the `child` and thus blocking<br>yourself from calling functions on `child` while using `stdin`, you might<br>find it helpful to do:<br><br>```no_run<br># let mut child = tokio::process::Command::new("echo").spawn().unwrap();<br>let stdin = child.stdin.take().unwrap();<br>``` |
| `stdout` | `Option<ChildStdout>` | The handle for reading from the child's standard output (stdout), if it<br>has been captured. You might find it helpful to do<br><br>```no_run<br># let mut child = tokio::process::Command::new("echo").spawn().unwrap();<br>let stdout = child.stdout.take().unwrap();<br>```<br><br>to avoid partially moving the `child` and thus blocking yourself from calling<br>functions on `child` while using `stdout`. |
| `stderr` | `Option<ChildStderr>` | The handle for reading from the child's standard error (stderr), if it<br>has been captured. You might find it helpful to do<br><br>```no_run<br># let mut child = tokio::process::Command::new("echo").spawn().unwrap();<br>let stderr = child.stderr.take().unwrap();<br>```<br><br>to avoid partially moving the `child` and thus blocking yourself from calling<br>functions on `child` while using `stderr`. |
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub fn id(self: &Self) -> Option<u32> { /* ... */ }
```
Returns the OS-assigned process identifier associated with this child
- ```rust
pub fn raw_handle(self: &Self) -> Option<RawHandle> { /* ... */ }
```
Extracts the raw handle of the process associated with this child while
- ```rust
pub fn start_kill(self: &mut Self) -> io::Result<()> { /* ... */ }
```
Attempts to force the child to exit, but does not wait for the request
- ```rust
pub async fn kill(self: &mut Self) -> io::Result<()> { /* ... */ }
```
Forces the child to exit.
- ```rust
pub async fn wait(self: &mut Self) -> io::Result<ExitStatus> { /* ... */ }
```
Waits for the child to exit completely, returning the status that it
- ```rust
pub fn try_wait(self: &mut Self) -> io::Result<Option<ExitStatus>> { /* ... */ }
```
Attempts to collect the exit status of the child if it has already
- ```rust
pub async fn wait_with_output(self: Self) -> io::Result<Output> { /* ... */ }
```
Returns a future that will resolve to an `Output`, containing the exit
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `ChildStdin`
The standard input stream for spawned children.
This type implements the `AsyncWrite` trait to pass data to the stdin
handle of a child process asynchronously.
```rust
pub struct ChildStdin {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub fn into_owned_fd(self: Self) -> io::Result<OwnedFd> { /* ... */ }
```
Convert into [`OwnedFd`].
- ```rust
pub fn into_owned_handle(self: Self) -> io::Result<OwnedHandle> { /* ... */ }
```
Convert into [`OwnedHandle`].
- ```rust
pub fn from_std(inner: std::process::ChildStdin) -> io::Result<Self> { /* ... */ }
```
Creates an asynchronous `ChildStdin` from a synchronous one.
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **AsFd**
- ```rust
fn as_fd(self: &Self) -> BorrowedFd<''_> { /* ... */ }
```
- **AsHandle**
- ```rust
fn as_handle(self: &Self) -> BorrowedHandle<''_> { /* ... */ }
```
- **AsRawFd**
- ```rust
fn as_raw_fd(self: &Self) -> RawFd { /* ... */ }
```
- **AsRawHandle**
- ```rust
fn as_raw_handle(self: &Self) -> RawHandle { /* ... */ }
```
- **AsyncWrite**
- ```rust
fn poll_write(self: Pin<&mut Self>, cx: &mut Context<''_>, buf: &[u8]) -> Poll<io::Result<usize>> { /* ... */ }
```
- ```rust
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<''_>) -> Poll<io::Result<()>> { /* ... */ }
```
- ```rust
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<''_>) -> Poll<io::Result<()>> { /* ... */ }
```
- ```rust
fn poll_write_vectored(self: Pin<&mut Self>, cx: &mut Context<''_>, bufs: &[io::IoSlice<''_>]) -> Poll<Result<usize, io::Error>> { /* ... */ }
```
- ```rust
fn is_write_vectored(self: &Self) -> bool { /* ... */ }
```
- **AsyncWriteExt**
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- ```rust
fn try_into(self: Self) -> Result<Stdio, <Self as >::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `ChildStdout`
The standard output stream for spawned children.
This type implements the `AsyncRead` trait to read data from the stdout
handle of a child process asynchronously.
```rust
pub struct ChildStdout {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub fn into_owned_fd(self: Self) -> io::Result<OwnedFd> { /* ... */ }
```
Convert into [`OwnedFd`].
- ```rust
pub fn into_owned_handle(self: Self) -> io::Result<OwnedHandle> { /* ... */ }
```
Convert into [`OwnedHandle`].
- ```rust
pub fn from_std(inner: std::process::ChildStdout) -> io::Result<Self> { /* ... */ }
```
Creates an asynchronous `ChildStdout` from a synchronous one.
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **AsFd**
- ```rust
fn as_fd(self: &Self) -> BorrowedFd<''_> { /* ... */ }
```
- **AsHandle**
- ```rust
fn as_handle(self: &Self) -> BorrowedHandle<''_> { /* ... */ }
```
- **AsRawFd**
- ```rust
fn as_raw_fd(self: &Self) -> RawFd { /* ... */ }
```
- **AsRawHandle**
- ```rust
fn as_raw_handle(self: &Self) -> RawHandle { /* ... */ }
```
- **AsyncRead**
- ```rust
fn poll_read(self: Pin<&mut Self>, cx: &mut Context<''_>, buf: &mut ReadBuf<''_>) -> Poll<io::Result<()>> { /* ... */ }
```
- **AsyncReadExt**
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- ```rust
fn try_into(self: Self) -> Result<Stdio, <Self as >::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `ChildStderr`
The standard error stream for spawned children.
This type implements the `AsyncRead` trait to read data from the stderr
handle of a child process asynchronously.
```rust
pub struct ChildStderr {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub fn into_owned_fd(self: Self) -> io::Result<OwnedFd> { /* ... */ }
```
Convert into [`OwnedFd`].
- ```rust
pub fn into_owned_handle(self: Self) -> io::Result<OwnedHandle> { /* ... */ }
```
Convert into [`OwnedHandle`].
- ```rust
pub fn from_std(inner: std::process::ChildStderr) -> io::Result<Self> { /* ... */ }
```
Creates an asynchronous `ChildStderr` from a synchronous one.
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **AsFd**
- ```rust
fn as_fd(self: &Self) -> BorrowedFd<''_> { /* ... */ }
```
- **AsHandle**
- ```rust
fn as_handle(self: &Self) -> BorrowedHandle<''_> { /* ... */ }
```
- **AsRawFd**
- ```rust
fn as_raw_fd(self: &Self) -> RawFd { /* ... */ }
```
- **AsRawHandle**
- ```rust
fn as_raw_handle(self: &Self) -> RawHandle { /* ... */ }
```
- **AsyncRead**
- ```rust
fn poll_read(self: Pin<&mut Self>, cx: &mut Context<''_>, buf: &mut ReadBuf<''_>) -> Poll<io::Result<()>> { /* ... */ }
```
- **AsyncReadExt**
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- ```rust
fn try_into(self: Self) -> Result<Stdio, <Self as >::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
## Module `runtime`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
The Tokio runtime.
Unlike other Rust programs, asynchronous applications require runtime
support. In particular, the following runtime services are necessary:
* An **I/O event loop**, called the driver, which drives I/O resources and
dispatches I/O events to tasks that depend on them.
* A **scheduler** to execute [tasks] that use these I/O resources.
* A **timer** for scheduling work to run after a set period of time.
Tokio's [`Runtime`] bundles all of these services as a single type, allowing
them to be started, shut down, and configured together. However, often it is
not required to configure a [`Runtime`] manually, and a user may just use the
[`tokio::main`] attribute macro, which creates a [`Runtime`] under the hood.
# Choose your runtime
Here is the rules of thumb to choose the right runtime for your application.
```plaintext
+------------------------------------------------------+
| Do you want work-stealing or multi-thread scheduler? |
+------------------------------------------------------+
| Yes | No
| |
| |
v |
+------------------------+ |
| Multi-threaded Runtime | |
+------------------------+ |
|
V
+--------------------------------+
| Do you execute `!Send` Future? |
+--------------------------------+
| Yes | No
| |
V |
+--------------------------+ |
| Local Runtime (unstable) | |
+--------------------------+ |
|
v
+------------------------+
| Current-thread Runtime |
+------------------------+
```
The above decision tree is not exhaustive. there are other factors that
may influence your decision.
## Bridging with sync code
See <https://tokio.rs/tokio/topics/bridging> for details.
## NUMA awareness
The tokio runtime is not NUMA (Non-Uniform Memory Access) aware.
You may want to start multiple runtimes instead of a single runtime
for better performance on NUMA systems.
# Usage
When no fine tuning is required, the [`tokio::main`] attribute macro can be
used.
```no_run
# #[cfg(not(target_family = "wasm"))]
# {
use tokio::net::TcpListener;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let listener = TcpListener::bind("127.0.0.1:8080").await?;
loop {
let (mut socket, _) = listener.accept().await?;
tokio::spawn(async move {
let mut buf = [0; 1024];
// In a loop, read data from the socket and write the data back.
loop {
let n = match socket.read(&mut buf).await {
// socket closed
Ok(0) => return,
Ok(n) => n,
Err(e) => {
println!("failed to read from socket; err = {:?}", e);
return;
}
};
// Write the data back
if let Err(e) = socket.write_all(&buf[0..n]).await {
println!("failed to write to socket; err = {:?}", e);
return;
}
}
});
}
}
# }
```
From within the context of the runtime, additional tasks are spawned using
the [`tokio::spawn`] function. Futures spawned using this function will be
executed on the same thread pool used by the [`Runtime`].
A [`Runtime`] instance can also be used directly.
```no_run
# #[cfg(not(target_family = "wasm"))]
# {
use tokio::net::TcpListener;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::runtime::Runtime;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create the runtime
let rt = Runtime::new()?;
// Spawn the root task
rt.block_on(async {
let listener = TcpListener::bind("127.0.0.1:8080").await?;
loop {
let (mut socket, _) = listener.accept().await?;
tokio::spawn(async move {
let mut buf = [0; 1024];
// In a loop, read data from the socket and write the data back.
loop {
let n = match socket.read(&mut buf).await {
// socket closed
Ok(0) => return,
Ok(n) => n,
Err(e) => {
println!("failed to read from socket; err = {:?}", e);
return;
}
};
// Write the data back
if let Err(e) = socket.write_all(&buf[0..n]).await {
println!("failed to write to socket; err = {:?}", e);
return;
}
}
});
}
})
}
# }
```
## Runtime Configurations
Tokio provides multiple task scheduling strategies, suitable for different
applications. The [runtime builder] or `#[tokio::main]` attribute may be
used to select which scheduler to use.
#### Multi-Thread Scheduler
The multi-thread scheduler executes futures on a _thread pool_, using a
work-stealing strategy. By default, it will start a worker thread for each
CPU core available on the system. This tends to be the ideal configuration
for most applications. The multi-thread scheduler requires the `rt-multi-thread`
feature flag, and is selected by default:
```
# #[cfg(not(target_family = "wasm"))]
# {
use tokio::runtime;
# fn main() -> Result<(), Box<dyn std::error::Error>> {
let threaded_rt = runtime::Runtime::new()?;
# Ok(()) }
# }
```
Most applications should use the multi-thread scheduler, except in some
niche use-cases, such as when running only a single thread is required.
#### Current-Thread Scheduler
The current-thread scheduler provides a _single-threaded_ future executor.
All tasks will be created and executed on the current thread. This requires
the `rt` feature flag.
```
use tokio::runtime;
# fn main() -> Result<(), Box<dyn std::error::Error>> {
let rt = runtime::Builder::new_current_thread()
.build()?;
# Ok(()) }
```
#### Resource drivers
When configuring a runtime by hand, no resource drivers are enabled by
default. In this case, attempting to use networking types or time types will
fail. In order to enable these types, the resource drivers must be enabled.
This is done with [`Builder::enable_io`] and [`Builder::enable_time`]. As a
shorthand, [`Builder::enable_all`] enables both resource drivers.
## Lifetime of spawned threads
The runtime may spawn threads depending on its configuration and usage. The
multi-thread scheduler spawns threads to schedule tasks and for `spawn_blocking`
calls.
While the `Runtime` is active, threads may shut down after periods of being
idle. Once `Runtime` is dropped, all runtime threads have usually been
terminated, but in the presence of unstoppable spawned work are not
guaranteed to have been terminated. See the
[struct level documentation](Runtime#shutdown) for more details.
[tasks]: crate::task
[`Runtime`]: Runtime
[`tokio::spawn`]: crate::spawn
[`tokio::main`]: ../attr.main.html
[runtime builder]: crate::runtime::Builder
[`Runtime::new`]: crate::runtime::Runtime::new
[`Builder::enable_io`]: crate::runtime::Builder::enable_io
[`Builder::enable_time`]: crate::runtime::Builder::enable_time
[`Builder::enable_all`]: crate::runtime::Builder::enable_all
# Detailed runtime behavior
This section gives more details into how the Tokio runtime will schedule
tasks for execution.
At its most basic level, a runtime has a collection of tasks that need to be
scheduled. It will repeatedly remove a task from that collection and
schedule it (by calling [`poll`]). When the collection is empty, the thread
will go to sleep until a task is added to the collection.
However, the above is not sufficient to guarantee a well-behaved runtime.
For example, the runtime might have a single task that is always ready to be
scheduled, and schedule that task every time. This is a problem because it
starves other tasks by not scheduling them. To solve this, Tokio provides
the following fairness guarantee:
> If the total number of tasks does not grow without bound, and no task is
> [blocking the thread], then it is guaranteed that tasks are scheduled
> fairly.
Or, more formally:
> Under the following two assumptions:
>
> * There is some number `MAX_TASKS` such that the total number of tasks on
> the runtime at any specific point in time never exceeds `MAX_TASKS`.
> * There is some number `MAX_SCHEDULE` such that calling [`poll`] on any
> task spawned on the runtime returns within `MAX_SCHEDULE` time units.
>
> Then, there is some number `MAX_DELAY` such that when a task is woken, it
> will be scheduled by the runtime within `MAX_DELAY` time units.
(Here, `MAX_TASKS` and `MAX_SCHEDULE` can be any number and the user of
the runtime may choose them. The `MAX_DELAY` number is controlled by the
runtime, and depends on the value of `MAX_TASKS` and `MAX_SCHEDULE`.)
Other than the above fairness guarantee, there is no guarantee about the
order in which tasks are scheduled. There is also no guarantee that the
runtime is equally fair to all tasks. For example, if the runtime has two
tasks A and B that are both ready, then the runtime may schedule A five
times before it schedules B. This is the case even if A yields using
[`yield_now`]. All that is guaranteed is that it will schedule B eventually.
Normally, tasks are scheduled only if they have been woken by calling
[`wake`] on their waker. However, this is not guaranteed, and Tokio may
schedule tasks that have not been woken under some circumstances. This is
called a spurious wakeup.
## IO and timers
Beyond just scheduling tasks, the runtime must also manage IO resources and
timers. It does this by periodically checking whether there are any IO
resources or timers that are ready, and waking the relevant task so that
it will be scheduled.
These checks are performed periodically between scheduling tasks. Under the
same assumptions as the previous fairness guarantee, Tokio guarantees that
it will wake tasks with an IO or timer event within some maximum number of
time units.
## Current thread runtime (behavior at the time of writing)
This section describes how the [current thread runtime] behaves today. This
behavior may change in future versions of Tokio.
The current thread runtime maintains two FIFO queues of tasks that are ready
to be scheduled: the global queue and the local queue. The runtime will prefer
to choose the next task to schedule from the local queue, and will only pick a
task from the global queue if the local queue is empty, or if it has picked
a task from the local queue 31 times in a row. The number 31 can be
changed using the [`global_queue_interval`] setting.
The runtime will check for new IO or timer events whenever there are no
tasks ready to be scheduled, or when it has scheduled 61 tasks in a row. The
number 61 may be changed using the [`event_interval`] setting.
When a task is woken from within a task running on the runtime, then the
woken task is added directly to the local queue. Otherwise, the task is
added to the global queue. The current thread runtime does not use [the lifo
slot optimization].
## Multi threaded runtime (behavior at the time of writing)
This section describes how the [multi thread runtime] behaves today. This
behavior may change in future versions of Tokio.
A multi thread runtime has a fixed number of worker threads, which are all
created on startup. The multi thread runtime maintains one global queue, and
a local queue for each worker thread. The local queue of a worker thread can
fit at most 256 tasks. If more than 256 tasks are added to the local queue,
then half of them are moved to the global queue to make space.
The runtime will prefer to choose the next task to schedule from the local
queue, and will only pick a task from the global queue if the local queue is
empty, or if it has picked a task from the local queue
[`global_queue_interval`] times in a row. If the value of
[`global_queue_interval`] is not explicitly set using the runtime builder,
then the runtime will dynamically compute it using a heuristic that targets
10ms intervals between each check of the global queue (based on the
[`worker_mean_poll_time`] metric).
If both the local queue and global queue is empty, then the worker thread
will attempt to steal tasks from the local queue of another worker thread.
Stealing is done by moving half of the tasks in one local queue to another
local queue.
The runtime will check for new IO or timer events whenever there are no
tasks ready to be scheduled, or when it has scheduled 61 tasks in a row. The
number 61 may be changed using the [`event_interval`] setting.
The multi thread runtime uses [the lifo slot optimization]: Whenever a task
wakes up another task, the other task is added to the worker thread's lifo
slot instead of being added to a queue. If there was already a task in the
lifo slot when this happened, then the lifo slot is replaced, and the task
that used to be in the lifo slot is placed in the thread's local queue.
When the runtime finishes scheduling a task, it will schedule the task in
the lifo slot immediately, if any. When the lifo slot is used, the [coop
budget] is not reset. Furthermore, if a worker thread uses the lifo slot
three times in a row, it is temporarily disabled until the worker thread has
scheduled a task that didn't come from the lifo slot. The lifo slot can be
disabled using the [`disable_lifo_slot`] setting. The lifo slot is separate
from the local queue, so other worker threads cannot steal the task in the
lifo slot.
When a task is woken from a thread that is not a worker thread, then the
task is placed in the global queue.
[`poll`]: std::future::Future::poll
[`wake`]: std::task::Waker::wake
[`yield_now`]: crate::task::yield_now
[blocking the thread]: https://ryhl.io/blog/async-what-is-blocking/
[current thread runtime]: crate::runtime::Builder::new_current_thread
[multi thread runtime]: crate::runtime::Builder::new_multi_thread
[`global_queue_interval`]: crate::runtime::Builder::global_queue_interval
[`event_interval`]: crate::runtime::Builder::event_interval
[`disable_lifo_slot`]: crate::runtime::Builder::disable_lifo_slot
[the lifo slot optimization]: crate::runtime::Builder::disable_lifo_slot
[coop budget]: crate::task::coop#cooperative-scheduling
[`worker_mean_poll_time`]: crate::runtime::RuntimeMetrics::worker_mean_poll_time
```rust
pub mod runtime { /* ... */ }
```
### Modules
## Module `dump`
**Attributes:**
- `Other("#[<cfg>(all(tokio_unstable, feature = \"taskdump\", feature = \"rt\", target_os =\n\"linux\",\nany(target_arch = \"aarch64\", target_arch = \"x86\", target_arch = \"x86_64\")))]")`
Snapshots of runtime state.
See [`Handle::dump`][crate::runtime::Handle::dump].
```rust
pub mod dump { /* ... */ }
```
### Types
#### Struct `Dump`
A snapshot of a runtime's state.
See [`Handle::dump`][crate::runtime::Handle::dump].
```rust
pub struct Dump {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub fn tasks(self: &Self) -> &Tasks { /* ... */ }
```
Tasks in this snapshot.
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `Tasks`
Snapshots of tasks.
See [`Handle::dump`][crate::runtime::Handle::dump].
```rust
pub struct Tasks {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub fn iter(self: &Self) -> impl Iterator<Item = &Task> { /* ... */ }
```
Iterate over tasks.
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `Task`
A snapshot of a task.
See [`Handle::dump`][crate::runtime::Handle::dump].
```rust
pub struct Task {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub fn id(self: &Self) -> Id { /* ... */ }
```
Returns a [task ID] that uniquely identifies this task relative to other
- ```rust
pub fn trace(self: &Self) -> &Trace { /* ... */ }
```
A trace of this task's state.
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `BacktraceSymbol`
A backtrace symbol.
This struct provides accessors for backtrace symbols, similar to [`backtrace::BacktraceSymbol`].
```rust
pub struct BacktraceSymbol {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub fn name_raw(self: &Self) -> Option<&[u8]> { /* ... */ }
```
Return the raw name of the symbol.
- ```rust
pub fn name_demangled(self: &Self) -> Option<&str> { /* ... */ }
```
Return the demangled name of the symbol.
- ```rust
pub fn addr(self: &Self) -> Option<*mut std::ffi::c_void> { /* ... */ }
```
Returns the starting address of this symbol.
- ```rust
pub fn filename(self: &Self) -> Option<&Path> { /* ... */ }
```
Returns the file name where this function was defined. If debuginfo
- ```rust
pub fn lineno(self: &Self) -> Option<u32> { /* ... */ }
```
Returns the line number for where this symbol is currently executing.
- ```rust
pub fn colno(self: &Self) -> Option<u32> { /* ... */ }
```
Returns the column number for where this symbol is currently executing.
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Clone**
- ```rust
fn clone(self: &Self) -> BacktraceSymbol { /* ... */ }
```
- **CloneToUninit**
- ```rust
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **ToOwned**
- ```rust
fn to_owned(self: &Self) -> T { /* ... */ }
```
- ```rust
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
```
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `BacktraceFrame`
A backtrace frame.
This struct represents one stack frame in a captured backtrace, similar to [`backtrace::BacktraceFrame`].
```rust
pub struct BacktraceFrame {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub fn ip(self: &Self) -> *mut std::ffi::c_void { /* ... */ }
```
Return the instruction pointer of this frame.
- ```rust
pub fn symbol_address(self: &Self) -> *mut std::ffi::c_void { /* ... */ }
```
Returns the starting symbol address of the frame of this function.
- ```rust
pub fn symbols(self: &Self) -> impl Iterator<Item = &BacktraceSymbol> { /* ... */ }
```
Return an iterator over the symbols of this backtrace frame.
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Clone**
- ```rust
fn clone(self: &Self) -> BacktraceFrame { /* ... */ }
```
- **CloneToUninit**
- ```rust
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **ToOwned**
- ```rust
fn to_owned(self: &Self) -> T { /* ... */ }
```
- ```rust
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
```
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `Backtrace`
A captured backtrace.
This struct provides access to each backtrace frame, similar to [`backtrace::Backtrace`].
```rust
pub struct Backtrace {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub fn frames(self: &Self) -> impl Iterator<Item = &BacktraceFrame> { /* ... */ }
```
Return the frames in this backtrace, innermost (in a task dump,
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Clone**
- ```rust
fn clone(self: &Self) -> Backtrace { /* ... */ }
```
- **CloneToUninit**
- ```rust
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **ToOwned**
- ```rust
fn to_owned(self: &Self) -> T { /* ... */ }
```
- ```rust
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
```
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `Trace`
An execution trace of a task's last poll.
<div class="warning">
Resolving a backtrace, either via the [`Display`][std::fmt::Display] impl or via
[`resolve_backtraces`][Trace::resolve_backtraces], parses debuginfo, which is
possibly a CPU-expensive operation that can take a platform-specific but
long time to run - often over 100 milliseconds, especially if the current
process's binary is big. In some cases, the platform might internally cache some of the
debuginfo, so successive calls to `resolve_backtraces` might be faster than
the first call, but all guarantees are platform-dependent.
To avoid blocking the runtime, it is recommended
that you resolve backtraces inside of a [`spawn_blocking()`][crate::task::spawn_blocking]
and to have some concurrency-limiting mechanism to avoid unexpected performance impact.
</div>
See [`Handle::dump`][crate::runtime::Handle::dump].
```rust
pub struct Trace {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub fn resolve_backtraces(self: &Self) -> Vec<Backtrace> { /* ... */ }
```
Resolve and return a list of backtraces that are involved in polls in this trace.
- ```rust
pub fn capture<F, R>(f: F) -> (R, Trace)
where
F: FnOnce() -> R { /* ... */ }
```
Runs the function `f` in tracing mode, and returns its result along with the resulting [`Trace`].
- ```rust
pub fn root<F>(f: F) -> Root<F>
where
F: Future { /* ... */ }
```
Create a root for stack traces captured using [`Trace::capture`]. Stack frames above
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Display**
- ```rust
fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **ToString**
- ```rust
fn to_string(self: &Self) -> String { /* ... */ }
```
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
### Re-exports
#### Re-export `Root`
```rust
pub use crate::runtime::task::trace::Root;
```
### Re-exports
#### Re-export `Builder`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
```rust
pub use self::builder::Builder;
```
#### Re-export `Id`
**Attributes:**
- `Other("#[<cfg>(tokio_unstable)]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(tokio_unstable)))]")`
- `Other("#[doc(cfg(tokio_unstable))]")`
- `Other("#[<cfg_attr>(not(tokio_unstable), allow(unreachable_pub))]")`
```rust
pub use id::Id;
```
#### Re-export `UnhandledPanic`
**Attributes:**
- `Other("#[<cfg>(tokio_unstable)]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(tokio_unstable)))]")`
- `Other("#[doc(cfg(tokio_unstable))]")`
```rust
pub use self::builder::UnhandledPanic;
```
#### Re-export `RngSeed`
**Attributes:**
- `Other("#[<cfg>(tokio_unstable)]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(tokio_unstable)))]")`
- `Other("#[doc(cfg(tokio_unstable))]")`
```rust
pub use crate::util::rand::RngSeed;
```
#### Re-export `LocalRuntime`
**Attributes:**
- `Other("#[<cfg>(tokio_unstable)]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(tokio_unstable)))]")`
- `Other("#[doc(cfg(tokio_unstable))]")`
```rust
pub use local_runtime::LocalRuntime;
```
#### Re-export `LocalOptions`
**Attributes:**
- `Other("#[<cfg>(tokio_unstable)]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(tokio_unstable)))]")`
- `Other("#[doc(cfg(tokio_unstable))]")`
```rust
pub use local_runtime::LocalOptions;
```
#### Re-export `Dump`
**Attributes:**
- `Other("#[<cfg>(all(tokio_unstable, feature = \"taskdump\", feature = \"rt\", target_os =\n\"linux\",\nany(target_arch = \"aarch64\", target_arch = \"x86\", target_arch = \"x86_64\")))]")`
```rust
pub use dump::Dump;
```
#### Re-export `TaskMeta`
**Attributes:**
- `Other("#[<cfg>(tokio_unstable)]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(tokio_unstable)))]")`
- `Other("#[doc(cfg(tokio_unstable))]")`
```rust
pub use task_hooks::TaskMeta;
```
#### Re-export `EnterGuard`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
```rust
pub use handle::EnterGuard;
```
#### Re-export `Handle`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
```rust
pub use handle::Handle;
```
#### Re-export `TryCurrentError`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
```rust
pub use handle::TryCurrentError;
```
#### Re-export `Runtime`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
```rust
pub use runtime::Runtime;
```
#### Re-export `RuntimeFlavor`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
```rust
pub use runtime::RuntimeFlavor;
```
#### Re-export `RuntimeMetrics`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
```rust
pub use metrics::RuntimeMetrics;
```
#### Re-export `HistogramScale`
**Attributes:**
- `Other("#[<cfg>(tokio_unstable)]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(tokio_unstable)))]")`
- `Other("#[doc(cfg(tokio_unstable))]")`
```rust
pub use metrics::HistogramScale;
```
#### Re-export `HistogramConfiguration`
**Attributes:**
- `Other("#[<cfg>(tokio_unstable)]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(tokio_unstable)))]")`
- `Other("#[doc(cfg(tokio_unstable))]")`
```rust
pub use metrics::HistogramConfiguration;
```
#### Re-export `LogHistogram`
**Attributes:**
- `Other("#[<cfg>(tokio_unstable)]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(tokio_unstable)))]")`
- `Other("#[doc(cfg(tokio_unstable))]")`
```rust
pub use metrics::LogHistogram;
```
#### Re-export `LogHistogramBuilder`
**Attributes:**
- `Other("#[<cfg>(tokio_unstable)]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(tokio_unstable)))]")`
- `Other("#[doc(cfg(tokio_unstable))]")`
```rust
pub use metrics::LogHistogramBuilder;
```
#### Re-export `InvalidHistogramConfiguration`
**Attributes:**
- `Other("#[<cfg>(tokio_unstable)]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(tokio_unstable)))]")`
- `Other("#[doc(cfg(tokio_unstable))]")`
```rust
pub use metrics::InvalidHistogramConfiguration;
```
## Module `signal`
**Attributes:**
- `Other("#[<cfg>(feature = \"signal\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"signal\")))]")`
- `Other("#[doc(cfg(feature = \"signal\"))]")`
- `Other("#[<cfg>(not(loom))]")`
- `Other("#[<cfg>(not(target_os = \"wasi\"))]")`
Asynchronous signal handling for Tokio.
Note that signal handling is in general a very tricky topic and should be
used with great care. This crate attempts to implement 'best practice' for
signal handling, but it should be evaluated for your own applications' needs
to see if it's suitable.
There are some fundamental limitations of this crate documented on the OS
specific structures, as well.
# Examples
Print on "ctrl-c" notification.
```rust,no_run
use tokio::signal;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
signal::ctrl_c().await?;
println!("ctrl-c received!");
Ok(())
}
```
Wait for `SIGHUP` on Unix
```rust,no_run
# #[cfg(unix)] {
use tokio::signal::unix::{signal, SignalKind};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// An infinite stream of hangup signals.
let mut stream = signal(SignalKind::hangup())?;
// Print whenever a HUP signal is received
loop {
stream.recv().await;
println!("got signal HUP");
}
}
# }
```
```rust
pub mod signal { /* ... */ }
```
### Modules
## Module `unix`
**Attributes:**
- `Other("#[<cfg>(unix)]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(all(unix, feature = \"signal\"))))]")`
- `Other("#[doc(cfg(all(unix, feature = \"signal\")))]")`
Unix-specific types for signal handling.
This module is only defined on Unix platforms and contains the primary
`Signal` type for receiving notifications of signals.
```rust
pub mod unix { /* ... */ }
```
### Types
#### Struct `SignalKind`
Represents the specific kind of signal to listen for.
```rust
pub struct SignalKind(/* private field */);
```
##### Fields
| Index | Type | Documentation |
|-------|------|---------------|
| 0 | `private` | *Private field* |
##### Implementations
###### Methods
- ```rust
pub const fn from_raw(signum: std::os::raw::c_int) -> Self { /* ... */ }
```
Allows for listening to any valid OS signal.
- ```rust
pub const fn as_raw_value(self: &Self) -> std::os::raw::c_int { /* ... */ }
```
Get the signal's numeric value.
- ```rust
pub const fn alarm() -> Self { /* ... */ }
```
Represents the `SIGALRM` signal.
- ```rust
pub const fn child() -> Self { /* ... */ }
```
Represents the `SIGCHLD` signal.
- ```rust
pub const fn hangup() -> Self { /* ... */ }
```
Represents the `SIGHUP` signal.
- ```rust
pub const fn interrupt() -> Self { /* ... */ }
```
Represents the `SIGINT` signal.
- ```rust
pub const fn io() -> Self { /* ... */ }
```
Represents the `SIGIO` signal.
- ```rust
pub const fn pipe() -> Self { /* ... */ }
```
Represents the `SIGPIPE` signal.
- ```rust
pub const fn quit() -> Self { /* ... */ }
```
Represents the `SIGQUIT` signal.
- ```rust
pub const fn terminate() -> Self { /* ... */ }
```
Represents the `SIGTERM` signal.
- ```rust
pub const fn user_defined1() -> Self { /* ... */ }
```
Represents the `SIGUSR1` signal.
- ```rust
pub const fn user_defined2() -> Self { /* ... */ }
```
Represents the `SIGUSR2` signal.
- ```rust
pub const fn window_change() -> Self { /* ... */ }
```
Represents the `SIGWINCH` signal.
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Clone**
- ```rust
fn clone(self: &Self) -> SignalKind { /* ... */ }
```
- **CloneToUninit**
- ```rust
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
```
- **Copy**
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Eq**
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- ```rust
fn from(signum: std::os::raw::c_int) -> Self { /* ... */ }
```
- ```rust
fn from(kind: SignalKind) -> Self { /* ... */ }
```
- **Hash**
- ```rust
fn hash<__H: $crate::hash::Hasher>(self: &Self, state: &mut __H) { /* ... */ }
```
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **PartialEq**
- ```rust
fn eq(self: &Self, other: &SignalKind) -> bool { /* ... */ }
```
- **RefUnwindSafe**
- **Send**
- **StructuralPartialEq**
- **Sync**
- **ToOwned**
- ```rust
fn to_owned(self: &Self) -> T { /* ... */ }
```
- ```rust
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
```
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `Signal`
**Attributes:**
- `MustUse { reason: Some("streams do nothing unless polled") }`
An listener for receiving a particular type of OS signal.
The listener can be turned into a `Stream` using [`SignalStream`].
[`SignalStream`]: https://docs.rs/tokio-stream/latest/tokio_stream/wrappers/struct.SignalStream.html
In general signal handling on Unix is a pretty tricky topic, and this
structure is no exception! There are some important limitations to keep in
mind when using `Signal` streams:
* Signals handling in Unix already necessitates coalescing signals
together sometimes. This `Signal` stream is also no exception here in
that it will also coalesce signals. That is, even if the signal handler
for this process runs multiple times, the `Signal` stream may only return
one signal notification. Specifically, before `poll` is called, all
signal notifications are coalesced into one item returned from `poll`.
Once `poll` has been called, however, a further signal is guaranteed to
be yielded as an item.
Put another way, any element pulled off the returned listener corresponds to
*at least one* signal, but possibly more.
* Signal handling in general is relatively inefficient. Although some
improvements are possible in this crate, it's recommended to not plan on
having millions of signal channels open.
If you've got any questions about this feel free to open an issue on the
repo! New approaches to alleviate some of these limitations are always
appreciated!
# Caveats
The first time that a `Signal` instance is registered for a particular
signal kind, an OS signal-handler is installed which replaces the default
platform behavior when that signal is received, **for the duration of the
entire process**.
For example, Unix systems will terminate a process by default when it
receives `SIGINT`. But, when a `Signal` instance is created to listen for
this signal, the next `SIGINT` that arrives will be translated to a stream
event, and the process will continue to execute. **Even if this `Signal`
instance is dropped, subsequent `SIGINT` deliveries will end up captured by
Tokio, and the default platform behavior will NOT be reset**.
Thus, applications should take care to ensure the expected signal behavior
occurs as expected after listening for specific signals.
# Examples
Wait for `SIGHUP`
```rust,no_run
use tokio::signal::unix::{signal, SignalKind};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// An infinite stream of hangup signals.
let mut sig = signal(SignalKind::hangup())?;
// Print whenever a HUP signal is received
loop {
sig.recv().await;
println!("got signal HUP");
}
}
```
```rust
pub struct Signal {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub async fn recv(self: &mut Self) -> Option<()> { /* ... */ }
```
Receives the next signal notification event.
- ```rust
pub fn poll_recv(self: &mut Self, cx: &mut Context<''_>) -> Poll<Option<()>> { /* ... */ }
```
Polls to receive the next signal notification event, outside of an
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
### Functions
#### Function `signal`
**Attributes:**
- `Other("#[attr = TrackCaller]")`
Creates a new listener which will receive notifications when the current
process receives the specified signal `kind`.
This function will create a new stream which binds to the default reactor.
The `Signal` stream is an infinite stream which will receive
notifications whenever a signal is received. More documentation can be
found on `Signal` itself, but to reiterate:
* Signals may be coalesced beyond what the kernel already does.
* Once a signal handler is registered with the process the underlying
libc signal handler is never unregistered.
A `Signal` stream can be created for a particular signal number
multiple times. When a signal is received then all the associated
channels will receive the signal notification.
# Errors
* If the lower-level C functions fail for some reason.
* If the previous initialization of this specific signal failed.
* If the signal is one of
[`signal_hook::FORBIDDEN`](fn@signal_hook_registry::register#panics)
# Panics
This function panics if there is no current reactor set, or if the `rt`
feature flag is not enabled.
```rust
pub fn signal(kind: SignalKind) -> io::Result<Signal> { /* ... */ }
```
## Module `windows`
**Attributes:**
- `Other("#[<cfg>(any(windows, docsrs))]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(all(windows, feature = \"signal\"))))]")`
- `Other("#[doc(cfg(all(windows, feature = \"signal\")))]")`
Windows-specific types for signal handling.
This module is only defined on Windows and allows receiving "ctrl-c",
"ctrl-break", "ctrl-logoff", "ctrl-shutdown", and "ctrl-close"
notifications. These events are listened for via the `SetConsoleCtrlHandler`
function which receives the corresponding `windows_sys` event type.
```rust
pub mod windows { /* ... */ }
```
### Types
#### Struct `CtrlC`
**Attributes:**
- `MustUse { reason: Some("listeners do nothing unless polled") }`
Represents a listener which receives "ctrl-c" notifications sent to the process
via `SetConsoleCtrlHandler`.
This event can be turned into a `Stream` using [`CtrlCStream`].
[`CtrlCStream`]: https://docs.rs/tokio-stream/latest/tokio_stream/wrappers/struct.CtrlCStream.html
A notification to this process notifies *all* receivers for
this event. Moreover, the notifications **are coalesced** if they aren't processed
quickly enough. This means that if two notifications are received back-to-back,
then the listener may only receive one item about the two notifications.
```rust
pub struct CtrlC {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub async fn recv(self: &mut Self) -> Option<()> { /* ... */ }
```
Receives the next signal notification event.
- ```rust
pub fn poll_recv(self: &mut Self, cx: &mut Context<''_>) -> Poll<Option<()>> { /* ... */ }
```
Polls to receive the next signal notification event, outside of an
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `CtrlBreak`
**Attributes:**
- `MustUse { reason: Some("listeners do nothing unless polled") }`
Represents a listener which receives "ctrl-break" notifications sent to the process
via `SetConsoleCtrlHandler`.
This listener can be turned into a `Stream` using [`CtrlBreakStream`].
[`CtrlBreakStream`]: https://docs.rs/tokio-stream/latest/tokio_stream/wrappers/struct.CtrlBreakStream.html
A notification to this process notifies *all* receivers for
this event. Moreover, the notifications **are coalesced** if they aren't processed
quickly enough. This means that if two notifications are received back-to-back,
then the listener may only receive one item about the two notifications.
```rust
pub struct CtrlBreak {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub async fn recv(self: &mut Self) -> Option<()> { /* ... */ }
```
Receives the next signal notification event.
- ```rust
pub fn poll_recv(self: &mut Self, cx: &mut Context<''_>) -> Poll<Option<()>> { /* ... */ }
```
Polls to receive the next signal notification event, outside of an
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `CtrlClose`
**Attributes:**
- `MustUse { reason: Some("listeners do nothing unless polled") }`
Represents a listener which receives "ctrl-close" notifications sent to the process
via `SetConsoleCtrlHandler`.
A notification to this process notifies *all* listeners listening for
this event. Moreover, the notifications **are coalesced** if they aren't processed
quickly enough. This means that if two notifications are received back-to-back,
then the listener may only receive one item about the two notifications.
```rust
pub struct CtrlClose {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub async fn recv(self: &mut Self) -> Option<()> { /* ... */ }
```
Receives the next signal notification event.
- ```rust
pub fn poll_recv(self: &mut Self, cx: &mut Context<''_>) -> Poll<Option<()>> { /* ... */ }
```
Polls to receive the next signal notification event, outside of an
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `CtrlShutdown`
**Attributes:**
- `MustUse { reason: Some("listeners do nothing unless polled") }`
Represents a listener which receives "ctrl-shutdown" notifications sent to the process
via `SetConsoleCtrlHandler`.
A notification to this process notifies *all* listeners listening for
this event. Moreover, the notifications **are coalesced** if they aren't processed
quickly enough. This means that if two notifications are received back-to-back,
then the listener may only receive one item about the two notifications.
```rust
pub struct CtrlShutdown {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub async fn recv(self: &mut Self) -> Option<()> { /* ... */ }
```
Receives the next signal notification event.
- ```rust
pub fn poll_recv(self: &mut Self, cx: &mut Context<''_>) -> Poll<Option<()>> { /* ... */ }
```
Polls to receive the next signal notification event, outside of an
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `CtrlLogoff`
**Attributes:**
- `MustUse { reason: Some("listeners do nothing unless polled") }`
Represents a listener which receives "ctrl-logoff" notifications sent to the process
via `SetConsoleCtrlHandler`.
A notification to this process notifies *all* listeners listening for
this event. Moreover, the notifications **are coalesced** if they aren't processed
quickly enough. This means that if two notifications are received back-to-back,
then the listener may only receive one item about the two notifications.
```rust
pub struct CtrlLogoff {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub async fn recv(self: &mut Self) -> Option<()> { /* ... */ }
```
Receives the next signal notification event.
- ```rust
pub fn poll_recv(self: &mut Self, cx: &mut Context<''_>) -> Poll<Option<()>> { /* ... */ }
```
Polls to receive the next signal notification event, outside of an
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
### Functions
#### Function `ctrl_c`
Creates a new listener which receives "ctrl-c" notifications sent to the
process.
# Examples
```rust,no_run
use tokio::signal::windows::ctrl_c;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// A listener of CTRL-C events.
let mut signal = ctrl_c()?;
// Print whenever a CTRL-C event is received.
for countdown in (0..3).rev() {
signal.recv().await;
println!("got CTRL-C. {} more to exit", countdown);
}
Ok(())
}
```
```rust
pub fn ctrl_c() -> io::Result<CtrlC> { /* ... */ }
```
#### Function `ctrl_break`
Creates a new listener which receives "ctrl-break" notifications sent to the
process.
# Examples
```rust,no_run
use tokio::signal::windows::ctrl_break;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// A listener of CTRL-BREAK events.
let mut signal = ctrl_break()?;
// Print whenever a CTRL-BREAK event is received.
loop {
signal.recv().await;
println!("got signal CTRL-BREAK");
}
}
```
```rust
pub fn ctrl_break() -> io::Result<CtrlBreak> { /* ... */ }
```
#### Function `ctrl_close`
Creates a new listener which receives "ctrl-close" notifications sent to the
process.
# Examples
```rust,no_run
use tokio::signal::windows::ctrl_close;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// A listener of CTRL-CLOSE events.
let mut signal = ctrl_close()?;
// Print whenever a CTRL-CLOSE event is received.
for countdown in (0..3).rev() {
signal.recv().await;
println!("got CTRL-CLOSE. {} more to exit", countdown);
}
Ok(())
}
```
```rust
pub fn ctrl_close() -> io::Result<CtrlClose> { /* ... */ }
```
#### Function `ctrl_shutdown`
Creates a new listener which receives "ctrl-shutdown" notifications sent to the
process.
# Examples
```rust,no_run
use tokio::signal::windows::ctrl_shutdown;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// A listener of CTRL-SHUTDOWN events.
let mut signal = ctrl_shutdown()?;
signal.recv().await;
println!("got CTRL-SHUTDOWN. Cleaning up before exiting");
Ok(())
}
```
```rust
pub fn ctrl_shutdown() -> io::Result<CtrlShutdown> { /* ... */ }
```
#### Function `ctrl_logoff`
Creates a new listener which receives "ctrl-logoff" notifications sent to the
process.
# Examples
```rust,no_run
use tokio::signal::windows::ctrl_logoff;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// A listener of CTRL-LOGOFF events.
let mut signal = ctrl_logoff()?;
signal.recv().await;
println!("got CTRL-LOGOFF. Cleaning up before exiting");
Ok(())
}
```
```rust
pub fn ctrl_logoff() -> io::Result<CtrlLogoff> { /* ... */ }
```
### Re-exports
#### Re-export `ctrl_c`
**Attributes:**
- `Other("#[<cfg>(feature = \"signal\")]")`
```rust
pub use ctrl_c::ctrl_c;
```
## Module `sync`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
- `Other("#[<cfg_attr>(loom, allow(dead_code, unreachable_pub, unused_imports))]")`
Synchronization primitives for use in asynchronous contexts.
Tokio programs tend to be organized as a set of [tasks] where each task
operates independently and may be executed on separate physical threads. The
synchronization primitives provided in this module permit these independent
tasks to communicate together.
[tasks]: crate::task
# Message passing
The most common form of synchronization in a Tokio program is message
passing. Two tasks operate independently and send messages to each other to
synchronize. Doing so has the advantage of avoiding shared state.
Message passing is implemented using channels. A channel supports sending a
message from one producer task to one or more consumer tasks. There are a
few flavors of channels provided by Tokio. Each channel flavor supports
different message passing patterns. When a channel supports multiple
producers, many separate tasks may **send** messages. When a channel
supports multiple consumers, many different separate tasks may **receive**
messages.
Tokio provides many different channel flavors as different message passing
patterns are best handled with different implementations.
## `oneshot` channel
The [`oneshot` channel][oneshot] supports sending a **single** value from a
single producer to a single consumer. This channel is usually used to send
the result of a computation to a waiter.
**Example:** using a [`oneshot` channel][oneshot] to receive the result of a
computation.
```
use tokio::sync::oneshot;
async fn some_computation() -> String {
"represents the result of the computation".to_string()
}
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let (tx, rx) = oneshot::channel();
tokio::spawn(async move {
let res = some_computation().await;
tx.send(res).unwrap();
});
// Do other work while the computation is happening in the background
// Wait for the computation result
let res = rx.await.unwrap();
# }
```
Note, if the task produces a computation result as its final
action before terminating, the [`JoinHandle`] can be used to
receive that value instead of allocating resources for the
`oneshot` channel. Awaiting on [`JoinHandle`] returns `Result`. If
the task panics, the `Joinhandle` yields `Err` with the panic
cause.
**Example:**
```
async fn some_computation() -> String {
"the result of the computation".to_string()
}
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let join_handle = tokio::spawn(async move {
some_computation().await
});
// Do other work while the computation is happening in the background
// Wait for the computation result
let res = join_handle.await.unwrap();
# }
```
[`JoinHandle`]: crate::task::JoinHandle
## `mpsc` channel
The [`mpsc` channel][mpsc] supports sending **many** values from **many**
producers to a single consumer. This channel is often used to send work to a
task or to receive the result of many computations.
This is also the channel you should use if you want to send many messages
from a single producer to a single consumer. There is no dedicated spsc
channel.
**Example:** using an mpsc to incrementally stream the results of a series
of computations.
```
use tokio::sync::mpsc;
async fn some_computation(input: u32) -> String {
format!("the result of computation {}", input)
}
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let (tx, mut rx) = mpsc::channel(100);
tokio::spawn(async move {
for i in 0..10 {
let res = some_computation(i).await;
tx.send(res).await.unwrap();
}
});
while let Some(res) = rx.recv().await {
println!("got = {}", res);
}
# }
```
The argument to `mpsc::channel` is the channel capacity. This is the maximum
number of values that can be stored in the channel pending receipt at any
given time. Properly setting this value is key in implementing robust
programs as the channel capacity plays a critical part in handling back
pressure.
A common concurrency pattern for resource management is to spawn a task
dedicated to managing that resource and using message passing between other
tasks to interact with the resource. The resource may be anything that may
not be concurrently used. Some examples include a socket and program state.
For example, if multiple tasks need to send data over a single socket, spawn
a task to manage the socket and use a channel to synchronize.
**Example:** sending data from many tasks over a single socket using message
passing.
```no_run
# #[cfg(not(target_family = "wasm"))]
# {
use tokio::io::{self, AsyncWriteExt};
use tokio::net::TcpStream;
use tokio::sync::mpsc;
#[tokio::main]
async fn main() -> io::Result<()> {
let mut socket = TcpStream::connect("www.example.com:1234").await?;
let (tx, mut rx) = mpsc::channel(100);
for _ in 0..10 {
// Each task needs its own `tx` handle. This is done by cloning the
// original handle.
let tx = tx.clone();
tokio::spawn(async move {
tx.send(&b"data to write"[..]).await.unwrap();
});
}
// The `rx` half of the channel returns `None` once **all** `tx` clones
// drop. To ensure `None` is returned, drop the handle owned by the
// current task. If this `tx` handle is not dropped, there will always
// be a single outstanding `tx` handle.
drop(tx);
while let Some(res) = rx.recv().await {
socket.write_all(res).await?;
}
Ok(())
}
# }
```
The [`mpsc`] and [`oneshot`] channels can be combined to provide a request /
response type synchronization pattern with a shared resource. A task is
spawned to synchronize a resource and waits on commands received on a
[`mpsc`] channel. Each command includes a [`oneshot`] `Sender` on which the
result of the command is sent.
**Example:** use a task to synchronize a `u64` counter. Each task sends an
"fetch and increment" command. The counter value **before** the increment is
sent over the provided `oneshot` channel.
```
use tokio::sync::{oneshot, mpsc};
use Command::Increment;
enum Command {
Increment,
// Other commands can be added here
}
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let (cmd_tx, mut cmd_rx) = mpsc::channel::<(Command, oneshot::Sender<u64>)>(100);
// Spawn a task to manage the counter
tokio::spawn(async move {
let mut counter: u64 = 0;
while let Some((cmd, response)) = cmd_rx.recv().await {
match cmd {
Increment => {
let prev = counter;
counter += 1;
response.send(prev).unwrap();
}
}
}
});
let mut join_handles = vec![];
// Spawn tasks that will send the increment command.
for _ in 0..10 {
let cmd_tx = cmd_tx.clone();
join_handles.push(tokio::spawn(async move {
let (resp_tx, resp_rx) = oneshot::channel();
cmd_tx.send((Increment, resp_tx)).await.ok().unwrap();
let res = resp_rx.await.unwrap();
println!("previous value = {}", res);
}));
}
// Wait for all tasks to complete
for join_handle in join_handles.drain(..) {
join_handle.await.unwrap();
}
# }
```
## `broadcast` channel
The [`broadcast` channel] supports sending **many** values from
**many** producers to **many** consumers. Each consumer will receive
**each** value. This channel can be used to implement "fan out" style
patterns common with pub / sub or "chat" systems.
This channel tends to be used less often than `oneshot` and `mpsc` but still
has its use cases.
This is also the channel you should use if you want to broadcast values from
a single producer to many consumers. There is no dedicated spmc broadcast
channel.
Basic usage
```
use tokio::sync::broadcast;
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let (tx, mut rx1) = broadcast::channel(16);
let mut rx2 = tx.subscribe();
tokio::spawn(async move {
assert_eq!(rx1.recv().await.unwrap(), 10);
assert_eq!(rx1.recv().await.unwrap(), 20);
});
tokio::spawn(async move {
assert_eq!(rx2.recv().await.unwrap(), 10);
assert_eq!(rx2.recv().await.unwrap(), 20);
});
tx.send(10).unwrap();
tx.send(20).unwrap();
# }
```
[`broadcast` channel]: crate::sync::broadcast
## `watch` channel
The [`watch` channel] supports sending **many** values from **many**
producers to **many** consumers. However, only the **most recent** value is
stored in the channel. Consumers are notified when a new value is sent, but
there is no guarantee that consumers will see **all** values.
The [`watch` channel] is similar to a [`broadcast` channel] with capacity 1.
Use cases for the [`watch` channel] include broadcasting configuration
changes or signalling program state changes, such as transitioning to
shutdown.
**Example:** use a [`watch` channel] to notify tasks of configuration
changes. In this example, a configuration file is checked periodically. When
the file changes, the configuration changes are signalled to consumers.
```
use tokio::sync::watch;
use tokio::time::{self, Duration, Instant};
use std::io;
#[derive(Debug, Clone, Eq, PartialEq)]
struct Config {
timeout: Duration,
}
impl Config {
async fn load_from_file() -> io::Result<Config> {
// file loading and deserialization logic here
# Ok(Config { timeout: Duration::from_secs(1) })
}
}
async fn my_async_operation() {
// Do something here
}
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
// Load initial configuration value
let mut config = Config::load_from_file().await.unwrap();
// Create the watch channel, initialized with the loaded configuration
let (tx, rx) = watch::channel(config.clone());
// Spawn a task to monitor the file.
tokio::spawn(async move {
loop {
// Wait 10 seconds between checks
time::sleep(Duration::from_secs(10)).await;
// Load the configuration file
let new_config = Config::load_from_file().await.unwrap();
// If the configuration changed, send the new config value
// on the watch channel.
if new_config != config {
tx.send(new_config.clone()).unwrap();
config = new_config;
}
}
});
let mut handles = vec![];
// Spawn tasks that runs the async operation for at most `timeout`. If
// the timeout elapses, restart the operation.
//
// The task simultaneously watches the `Config` for changes. When the
// timeout duration changes, the timeout is updated without restarting
// the in-flight operation.
for _ in 0..5 {
// Clone a config watch handle for use in this task
let mut rx = rx.clone();
let handle = tokio::spawn(async move {
// Start the initial operation and pin the future to the stack.
// Pinning to the stack is required to resume the operation
// across multiple calls to `select!`
let op = my_async_operation();
tokio::pin!(op);
// Get the initial config value
let mut conf = rx.borrow().clone();
let mut op_start = Instant::now();
let sleep = time::sleep_until(op_start + conf.timeout);
tokio::pin!(sleep);
loop {
tokio::select! {
_ = &mut sleep => {
// The operation elapsed. Restart it
op.set(my_async_operation());
// Track the new start time
op_start = Instant::now();
// Restart the timeout
sleep.set(time::sleep_until(op_start + conf.timeout));
}
_ = rx.changed() => {
conf = rx.borrow_and_update().clone();
// The configuration has been updated. Update the
// `sleep` using the new `timeout` value.
sleep.as_mut().reset(op_start + conf.timeout);
}
_ = &mut op => {
// The operation completed!
return
}
}
}
});
handles.push(handle);
}
for handle in handles.drain(..) {
handle.await.unwrap();
}
# }
```
[`watch` channel]: mod@crate::sync::watch
[`broadcast` channel]: mod@crate::sync::broadcast
# State synchronization
The remaining synchronization primitives focus on synchronizing state.
These are asynchronous equivalents to versions provided by `std`. They
operate in a similar way as their `std` counterparts but will wait
asynchronously instead of blocking the thread.
* [`Barrier`] Ensures multiple tasks will wait for each other to reach a
point in the program, before continuing execution all together.
* [`Mutex`] Mutual Exclusion mechanism, which ensures that at most one
thread at a time is able to access some data.
* [`Notify`] Basic task notification. `Notify` supports notifying a
receiving task without sending data. In this case, the task wakes up and
resumes processing.
* [`RwLock`] Provides a mutual exclusion mechanism which allows multiple
readers at the same time, while allowing only one writer at a time. In
some cases, this can be more efficient than a mutex.
* [`Semaphore`] Limits the amount of concurrency. A semaphore holds a
number of permits, which tasks may request in order to enter a critical
section. Semaphores are useful for implementing limiting or bounding of
any kind.
# Runtime compatibility
All synchronization primitives provided in this module are runtime agnostic.
You can freely move them between different instances of the Tokio runtime
or even use them from non-Tokio runtimes.
When used in a Tokio runtime, the synchronization primitives participate in
[cooperative scheduling](crate::task::coop#cooperative-scheduling) to avoid
starvation. This feature does not apply when used from non-Tokio runtimes.
As an exception, methods ending in `_timeout` are not runtime agnostic
because they require access to the Tokio timer. See the documentation of
each `*_timeout` method for more information on its use.
```rust
pub mod sync { /* ... */ }
```
### Modules
## Module `futures`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
Named future types.
```rust
pub mod futures { /* ... */ }
```
### Re-exports
#### Re-export `Notified`
```rust
pub use super::notify::Notified;
```
#### Re-export `OwnedNotified`
```rust
pub use super::notify::OwnedNotified;
```
## Module `broadcast`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
A multi-producer, multi-consumer broadcast queue. Each sent value is seen by
all consumers.
A [`Sender`] is used to broadcast values to **all** connected [`Receiver`]
values. [`Sender`] handles are clone-able, allowing concurrent send and
receive actions. [`Sender`] and [`Receiver`] are both `Send` and `Sync` as
long as `T` is `Send`.
When a value is sent, **all** [`Receiver`] handles are notified and will
receive the value. The value is stored once inside the channel and cloned on
demand for each receiver. Once all receivers have received a clone of the
value, the value is released from the channel.
A channel is created by calling [`channel`], specifying the maximum number
of messages the channel can retain at any given time.
New [`Receiver`] handles are created by calling [`Sender::subscribe`]. The
returned [`Receiver`] will receive values sent **after** the call to
`subscribe`.
This channel is also suitable for the single-producer multi-consumer
use-case, where a single sender broadcasts values to many receivers.
## Lagging
As sent messages must be retained until **all** [`Receiver`] handles receive
a clone, broadcast channels are susceptible to the "slow receiver" problem.
In this case, all but one receiver are able to receive values at the rate
they are sent. Because one receiver is stalled, the channel starts to fill
up.
This broadcast channel implementation handles this case by setting a hard
upper bound on the number of values the channel may retain at any given
time. This upper bound is passed to the [`channel`] function as an argument.
If a value is sent when the channel is at capacity, the oldest value
currently held by the channel is released. This frees up space for the new
value. Any receiver that has not yet seen the released value will return
[`RecvError::Lagged`] the next time [`recv`] is called.
Once [`RecvError::Lagged`] is returned, the lagging receiver's position is
updated to the oldest value contained by the channel. The next call to
[`recv`] will return this value.
This behavior enables a receiver to detect when it has lagged so far behind
that data has been dropped. The caller may decide how to respond to this:
either by aborting its task or by tolerating lost messages and resuming
consumption of the channel.
## Closing
When **all** [`Sender`] handles have been dropped, no new values may be
sent. At this point, the channel is "closed". Once a receiver has received
all values retained by the channel, the next call to [`recv`] will return
with [`RecvError::Closed`].
When a [`Receiver`] handle is dropped, any messages not read by the receiver
will be marked as read. If this receiver was the only one not to have read
that message, the message will be dropped at this point.
[`Sender`]: crate::sync::broadcast::Sender
[`Sender::subscribe`]: crate::sync::broadcast::Sender::subscribe
[`Receiver`]: crate::sync::broadcast::Receiver
[`channel`]: crate::sync::broadcast::channel
[`RecvError::Lagged`]: crate::sync::broadcast::error::RecvError::Lagged
[`RecvError::Closed`]: crate::sync::broadcast::error::RecvError::Closed
[`recv`]: crate::sync::broadcast::Receiver::recv
# Examples
Basic usage
```
use tokio::sync::broadcast;
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let (tx, mut rx1) = broadcast::channel(16);
let mut rx2 = tx.subscribe();
tokio::spawn(async move {
assert_eq!(rx1.recv().await.unwrap(), 10);
assert_eq!(rx1.recv().await.unwrap(), 20);
});
tokio::spawn(async move {
assert_eq!(rx2.recv().await.unwrap(), 10);
assert_eq!(rx2.recv().await.unwrap(), 20);
});
tx.send(10).unwrap();
tx.send(20).unwrap();
# }
```
Handling lag
```
use tokio::sync::broadcast;
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let (tx, mut rx) = broadcast::channel(2);
tx.send(10).unwrap();
tx.send(20).unwrap();
tx.send(30).unwrap();
// The receiver lagged behind
assert!(rx.recv().await.is_err());
// At this point, we can abort or continue with lost messages
assert_eq!(20, rx.recv().await.unwrap());
assert_eq!(30, rx.recv().await.unwrap());
# }
```
```rust
pub mod broadcast { /* ... */ }
```
### Modules
## Module `error`
Broadcast error types
```rust
pub mod error { /* ... */ }
```
### Types
#### Struct `SendError`
Error returned by the [`send`] function on a [`Sender`].
A **send** operation can only fail if there are no active receivers,
implying that the message could never be received. The error contains the
message being sent as a payload so it can be recovered.
[`send`]: crate::sync::broadcast::Sender::send
[`Sender`]: crate::sync::broadcast::Sender
```rust
pub struct SendError<T>(pub T);
```
##### Fields
| Index | Type | Documentation |
|-------|------|---------------|
| 0 | `T` | |
##### Implementations
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Display**
- ```rust
fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
```
- **Error**
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **ToString**
- ```rust
fn to_string(self: &Self) -> String { /* ... */ }
```
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Enum `RecvError`
An error returned from the [`recv`] function on a [`Receiver`].
[`recv`]: crate::sync::broadcast::Receiver::recv
[`Receiver`]: crate::sync::broadcast::Receiver
```rust
pub enum RecvError {
Closed,
Lagged(u64),
}
```
##### Variants
###### `Closed`
There are no more active senders implying no further messages will ever
be sent.
###### `Lagged`
The receiver lagged too far behind. Attempting to receive again will
return the oldest message still retained by the channel.
Includes the number of skipped messages.
Fields:
| Index | Type | Documentation |
|-------|------|---------------|
| 0 | `u64` | |
##### Implementations
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Clone**
- ```rust
fn clone(self: &Self) -> RecvError { /* ... */ }
```
- **CloneToUninit**
- ```rust
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Display**
- ```rust
fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
```
- **Eq**
- **Error**
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **PartialEq**
- ```rust
fn eq(self: &Self, other: &RecvError) -> bool { /* ... */ }
```
- **RefUnwindSafe**
- **Send**
- **StructuralPartialEq**
- **Sync**
- **ToOwned**
- ```rust
fn to_owned(self: &Self) -> T { /* ... */ }
```
- ```rust
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
```
- **ToString**
- ```rust
fn to_string(self: &Self) -> String { /* ... */ }
```
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Enum `TryRecvError`
An error returned from the [`try_recv`] function on a [`Receiver`].
[`try_recv`]: crate::sync::broadcast::Receiver::try_recv
[`Receiver`]: crate::sync::broadcast::Receiver
```rust
pub enum TryRecvError {
Empty,
Closed,
Lagged(u64),
}
```
##### Variants
###### `Empty`
The channel is currently empty. There are still active
[`Sender`] handles, so data may yet become available.
[`Sender`]: crate::sync::broadcast::Sender
###### `Closed`
There are no more active senders implying no further messages will ever
be sent.
###### `Lagged`
The receiver lagged too far behind and has been forcibly disconnected.
Attempting to receive again will return the oldest message still
retained by the channel.
Includes the number of skipped messages.
Fields:
| Index | Type | Documentation |
|-------|------|---------------|
| 0 | `u64` | |
##### Implementations
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Clone**
- ```rust
fn clone(self: &Self) -> TryRecvError { /* ... */ }
```
- **CloneToUninit**
- ```rust
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Display**
- ```rust
fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
```
- **Eq**
- **Error**
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **PartialEq**
- ```rust
fn eq(self: &Self, other: &TryRecvError) -> bool { /* ... */ }
```
- **RefUnwindSafe**
- **Send**
- **StructuralPartialEq**
- **Sync**
- **ToOwned**
- ```rust
fn to_owned(self: &Self) -> T { /* ... */ }
```
- ```rust
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
```
- **ToString**
- ```rust
fn to_string(self: &Self) -> String { /* ... */ }
```
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
### Types
#### Struct `Sender`
Sending-half of the [`broadcast`] channel.
May be used from many threads. Messages can be sent with
[`send`][Sender::send].
# Examples
```
use tokio::sync::broadcast;
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let (tx, mut rx1) = broadcast::channel(16);
let mut rx2 = tx.subscribe();
tokio::spawn(async move {
assert_eq!(rx1.recv().await.unwrap(), 10);
assert_eq!(rx1.recv().await.unwrap(), 20);
});
tokio::spawn(async move {
assert_eq!(rx2.recv().await.unwrap(), 10);
assert_eq!(rx2.recv().await.unwrap(), 20);
});
tx.send(10).unwrap();
tx.send(20).unwrap();
# }
```
[`broadcast`]: crate::sync::broadcast
```rust
pub struct Sender<T> {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub fn new(capacity: usize) -> Self { /* ... */ }
```
Creates the sending-half of the [`broadcast`] channel.
- ```rust
pub fn send(self: &Self, value: T) -> Result<usize, SendError<T>> { /* ... */ }
```
Attempts to send a value to all active [`Receiver`] handles, returning
- ```rust
pub fn subscribe(self: &Self) -> Receiver<T> { /* ... */ }
```
Creates a new [`Receiver`] handle that will receive values sent **after**
- ```rust
pub fn downgrade(self: &Self) -> WeakSender<T> { /* ... */ }
```
Converts the `Sender` to a [`WeakSender`] that does not count
- ```rust
pub fn len(self: &Self) -> usize { /* ... */ }
```
Returns the number of queued values.
- ```rust
pub fn is_empty(self: &Self) -> bool { /* ... */ }
```
Returns true if there are no queued values.
- ```rust
pub fn receiver_count(self: &Self) -> usize { /* ... */ }
```
Returns the number of active receivers.
- ```rust
pub fn same_channel(self: &Self, other: &Self) -> bool { /* ... */ }
```
Returns `true` if senders belong to the same channel.
- ```rust
pub async fn closed(self: &Self) { /* ... */ }
```
A future which completes when the number of [Receiver]s subscribed to this `Sender` reaches
- ```rust
pub fn strong_count(self: &Self) -> usize { /* ... */ }
```
Returns the number of [`Sender`] handles.
- ```rust
pub fn weak_count(self: &Self) -> usize { /* ... */ }
```
Returns the number of [`WeakSender`] handles.
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Clone**
- ```rust
fn clone(self: &Self) -> Sender<T> { /* ... */ }
```
- **CloneToUninit**
- ```rust
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, fmt: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
```
- **Drop**
- ```rust
fn drop(self: &mut Self) { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **ToOwned**
- ```rust
fn to_owned(self: &Self) -> T { /* ... */ }
```
- ```rust
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
```
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `WeakSender`
A sender that does not prevent the channel from being closed.
If all [`Sender`] instances of a channel were dropped and only `WeakSender`
instances remain, the channel is closed.
In order to send messages, the `WeakSender` needs to be upgraded using
[`WeakSender::upgrade`], which returns `Option<Sender>`. It returns `None`
if all `Sender`s have been dropped, and otherwise it returns a `Sender`.
[`Sender`]: Sender
[`WeakSender::upgrade`]: WeakSender::upgrade
# Examples
```
use tokio::sync::broadcast::channel;
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let (tx, _rx) = channel::<i32>(15);
let tx_weak = tx.downgrade();
// Upgrading will succeed because `tx` still exists.
assert!(tx_weak.upgrade().is_some());
// If we drop `tx`, then it will fail.
drop(tx);
assert!(tx_weak.clone().upgrade().is_none());
# }
```
```rust
pub struct WeakSender<T> {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub fn upgrade(self: &Self) -> Option<Sender<T>> { /* ... */ }
```
Tries to convert a `WeakSender` into a [`Sender`].
- ```rust
pub fn strong_count(self: &Self) -> usize { /* ... */ }
```
Returns the number of [`Sender`] handles.
- ```rust
pub fn weak_count(self: &Self) -> usize { /* ... */ }
```
Returns the number of [`WeakSender`] handles.
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Clone**
- ```rust
fn clone(self: &Self) -> WeakSender<T> { /* ... */ }
```
- **CloneToUninit**
- ```rust
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, fmt: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
```
- **Drop**
- ```rust
fn drop(self: &mut Self) { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **ToOwned**
- ```rust
fn to_owned(self: &Self) -> T { /* ... */ }
```
- ```rust
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
```
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `Receiver`
Receiving-half of the [`broadcast`] channel.
Must not be used concurrently. Messages may be retrieved using
[`recv`][Receiver::recv].
To turn this receiver into a `Stream`, you can use the [`BroadcastStream`]
wrapper.
[`BroadcastStream`]: https://docs.rs/tokio-stream/0.1/tokio_stream/wrappers/struct.BroadcastStream.html
# Examples
```
use tokio::sync::broadcast;
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let (tx, mut rx1) = broadcast::channel(16);
let mut rx2 = tx.subscribe();
tokio::spawn(async move {
assert_eq!(rx1.recv().await.unwrap(), 10);
assert_eq!(rx1.recv().await.unwrap(), 20);
});
tokio::spawn(async move {
assert_eq!(rx2.recv().await.unwrap(), 10);
assert_eq!(rx2.recv().await.unwrap(), 20);
});
tx.send(10).unwrap();
tx.send(20).unwrap();
# }
```
[`broadcast`]: crate::sync::broadcast
```rust
pub struct Receiver<T> {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub fn len(self: &Self) -> usize { /* ... */ }
```
Returns the number of messages that were sent into the channel and that
- ```rust
pub fn is_empty(self: &Self) -> bool { /* ... */ }
```
Returns true if there aren't any messages in the channel that the [`Receiver`]
- ```rust
pub fn same_channel(self: &Self, other: &Self) -> bool { /* ... */ }
```
Returns `true` if receivers belong to the same channel.
- ```rust
pub fn sender_strong_count(self: &Self) -> usize { /* ... */ }
```
Returns the number of [`Sender`] handles.
- ```rust
pub fn sender_weak_count(self: &Self) -> usize { /* ... */ }
```
Returns the number of [`WeakSender`] handles.
- ```rust
pub fn is_closed(self: &Self) -> bool { /* ... */ }
```
Checks if a channel is closed.
- ```rust
pub fn resubscribe(self: &Self) -> Self { /* ... */ }
```
Re-subscribes to the channel starting from the current tail element.
- ```rust
pub async fn recv(self: &mut Self) -> Result<T, RecvError> { /* ... */ }
```
Receives the next value for this receiver.
- ```rust
pub fn try_recv(self: &mut Self) -> Result<T, TryRecvError> { /* ... */ }
```
Attempts to return a pending value on this receiver without awaiting.
- ```rust
pub fn blocking_recv(self: &mut Self) -> Result<T, RecvError> { /* ... */ }
```
Blocking receive to call outside of asynchronous contexts.
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, fmt: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
```
- **Drop**
- ```rust
fn drop(self: &mut Self) { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
### Functions
#### Function `channel`
**Attributes:**
- `Other("#[attr = TrackCaller]")`
Create a bounded, multi-producer, multi-consumer channel where each sent
value is broadcasted to all active receivers.
**Note:** The actual capacity may be greater than the provided `capacity`.
All data sent on [`Sender`] will become available on every active
[`Receiver`] in the same order as it was sent.
The `Sender` can be cloned to `send` to the same channel from multiple
points in the process or it can be used concurrently from an `Arc`. New
`Receiver` handles are created by calling [`Sender::subscribe`].
If all [`Receiver`] handles are dropped, the `send` method will return a
[`SendError`]. Similarly, if all [`Sender`] handles are dropped, the [`recv`]
method will return a [`RecvError`].
[`Sender`]: crate::sync::broadcast::Sender
[`Sender::subscribe`]: crate::sync::broadcast::Sender::subscribe
[`Receiver`]: crate::sync::broadcast::Receiver
[`recv`]: crate::sync::broadcast::Receiver::recv
[`SendError`]: crate::sync::broadcast::error::SendError
[`RecvError`]: crate::sync::broadcast::error::RecvError
# Examples
```
use tokio::sync::broadcast;
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let (tx, mut rx1) = broadcast::channel(16);
let mut rx2 = tx.subscribe();
tokio::spawn(async move {
assert_eq!(rx1.recv().await.unwrap(), 10);
assert_eq!(rx1.recv().await.unwrap(), 20);
});
tokio::spawn(async move {
assert_eq!(rx2.recv().await.unwrap(), 10);
assert_eq!(rx2.recv().await.unwrap(), 20);
});
tx.send(10).unwrap();
tx.send(20).unwrap();
# }
```
# Panics
This will panic if `capacity` is equal to `0`.
This pre-allocates space for `capacity` messages. Allocation failure may result in a panic or
[an allocation error](std::alloc::handle_alloc_error).
```rust
pub fn channel<T: Clone>(capacity: usize) -> (Sender<T>, Receiver<T>) { /* ... */ }
```
## Module `mpsc`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
- `Other("#[<cfg_attr>(not(feature = \"sync\"), allow(dead_code, unreachable_pub))]")`
A multi-producer, single-consumer queue for sending values between
asynchronous tasks.
This module provides two variants of the channel: bounded and unbounded. The
bounded variant has a limit on the number of messages that the channel can
store, and if this limit is reached, trying to send another message will
wait until a message is received from the channel. An unbounded channel has
an infinite capacity, so the `send` method will always complete immediately.
This makes the [`UnboundedSender`] usable from both synchronous and
asynchronous code.
Similar to the `mpsc` channels provided by `std`, the channel constructor
functions provide separate send and receive handles, [`Sender`] and
[`Receiver`] for the bounded channel, [`UnboundedSender`] and
[`UnboundedReceiver`] for the unbounded channel. If there is no message to read,
the current task will be notified when a new value is sent. [`Sender`] and
[`UnboundedSender`] allow sending values into the channel. If the bounded
channel is at capacity, the send is rejected and the task will be notified
when additional capacity is available. In other words, the channel provides
backpressure.
This channel is also suitable for the single-producer single-consumer
use-case. (Unless you only need to send one message, in which case you
should use the [oneshot] channel.)
# Disconnection
When all [`Sender`] handles have been dropped, it is no longer
possible to send values into the channel. This is considered the termination
event of the stream. As such, `Receiver::poll` returns `Ok(Ready(None))`.
If the [`Receiver`] handle is dropped, then messages can no longer
be read out of the channel. In this case, all further attempts to send will
result in an error. Additionally, all unread messages will be drained from the
channel and dropped.
# Clean Shutdown
When the [`Receiver`] is dropped, it is possible for unprocessed messages to
remain in the channel. Instead, it is usually desirable to perform a "clean"
shutdown. To do this, the receiver first calls `close`, which will prevent
any further messages to be sent into the channel. Then, the receiver
consumes the channel to completion, at which point the receiver can be
dropped.
# Communicating between sync and async code
When you want to communicate between synchronous and asynchronous code, there
are two situations to consider:
**Bounded channel**: If you need a bounded channel, you should use a bounded
Tokio `mpsc` channel for both directions of communication. Instead of calling
the async [`send`][bounded-send] or [`recv`][bounded-recv] methods, in
synchronous code you will need to use the [`blocking_send`][blocking-send] or
[`blocking_recv`][blocking-recv] methods.
**Unbounded channel**: You should use the kind of channel that matches where
the receiver is. So for sending a message _from async to sync_, you should
use [the standard library unbounded channel][std-unbounded] or
[crossbeam][crossbeam-unbounded]. Similarly, for sending a message _from sync
to async_, you should use an unbounded Tokio `mpsc` channel.
Please be aware that the above remarks were written with the `mpsc` channel
in mind, but they can also be generalized to other kinds of channels. In
general, any channel method that isn't marked async can be called anywhere,
including outside of the runtime. For example, sending a message on a
[oneshot] channel from outside the runtime is perfectly fine.
# Multiple runtimes
The `mpsc` channel is runtime agnostic. You can freely move it between
different instances of the Tokio runtime or even use it from non-Tokio
runtimes.
When used in a Tokio runtime, it participates in
[cooperative scheduling](crate::task::coop#cooperative-scheduling) to avoid
starvation. This feature does not apply when used from non-Tokio runtimes.
As an exception, methods ending in `_timeout` are not runtime agnostic
because they require access to the Tokio timer. See the documentation of
each `*_timeout` method for more information on its use.
# Allocation behavior
<div class="warning">The implementation details described in this section may change in future
Tokio releases.</div>
The mpsc channel stores elements in blocks. Blocks are organized in a linked list. Sending
pushes new elements onto the block at the front of the list, and receiving pops them off the
one at the back. A block can hold 32 messages on a 64-bit target and 16 messages on a 32-bit
target. This number is independent of channel and message size. Each block also stores 4
pointer-sized values for bookkeeping (so on a 64-bit machine, each message has 1 byte of
overhead).
When all values in a block have been received, it becomes empty. It will then be freed, unless
the channel's first block (where newly-sent elements are being stored) has no next block. In
that case, the empty block is reused as the next block.
[`Sender`]: crate::sync::mpsc::Sender
[`Receiver`]: crate::sync::mpsc::Receiver
[bounded-send]: crate::sync::mpsc::Sender::send()
[bounded-recv]: crate::sync::mpsc::Receiver::recv()
[blocking-send]: crate::sync::mpsc::Sender::blocking_send()
[blocking-recv]: crate::sync::mpsc::Receiver::blocking_recv()
[`UnboundedSender`]: crate::sync::mpsc::UnboundedSender
[`UnboundedReceiver`]: crate::sync::mpsc::UnboundedReceiver
[oneshot]: crate::sync::oneshot
[`Handle::block_on`]: crate::runtime::Handle::block_on()
[std-unbounded]: std::sync::mpsc::channel
[crossbeam-unbounded]: https://docs.rs/crossbeam/*/crossbeam/channel/fn.unbounded.html
[`send_timeout`]: crate::sync::mpsc::Sender::send_timeout
```rust
pub mod mpsc { /* ... */ }
```
### Modules
## Module `error`
Channel error types.
```rust
pub mod error { /* ... */ }
```
### Types
#### Struct `SendError`
Error returned by the `Sender`.
```rust
pub struct SendError<T>(pub T);
```
##### Fields
| Index | Type | Documentation |
|-------|------|---------------|
| 0 | `T` | |
##### Implementations
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Clone**
- ```rust
fn clone(self: &Self) -> SendError<T> { /* ... */ }
```
- **CloneToUninit**
- ```rust
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
```
- **Copy**
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
```
- **Display**
- ```rust
fn fmt(self: &Self, fmt: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
```
- **Eq**
- **Error**
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- ```rust
fn from(src: SendError<T>) -> TrySendError<T> { /* ... */ }
```
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **PartialEq**
- ```rust
fn eq(self: &Self, other: &SendError<T>) -> bool { /* ... */ }
```
- **RefUnwindSafe**
- **Send**
- **StructuralPartialEq**
- **Sync**
- **ToOwned**
- ```rust
fn to_owned(self: &Self) -> T { /* ... */ }
```
- ```rust
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
```
- **ToString**
- ```rust
fn to_string(self: &Self) -> String { /* ... */ }
```
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Enum `TrySendError`
This enumeration is the list of the possible error outcomes for the
[`try_send`](super::Sender::try_send) method.
```rust
pub enum TrySendError<T> {
Full(T),
Closed(T),
}
```
##### Variants
###### `Full`
The data could not be sent on the channel because the channel is
currently full and sending would require blocking.
Fields:
| Index | Type | Documentation |
|-------|------|---------------|
| 0 | `T` | |
###### `Closed`
The receive half of the channel was explicitly closed or has been
dropped.
Fields:
| Index | Type | Documentation |
|-------|------|---------------|
| 0 | `T` | |
##### Implementations
###### Methods
- ```rust
pub fn into_inner(self: Self) -> T { /* ... */ }
```
Consume the `TrySendError`, returning the unsent value.
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Clone**
- ```rust
fn clone(self: &Self) -> TrySendError<T> { /* ... */ }
```
- **CloneToUninit**
- ```rust
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
```
- **Copy**
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
```
- **Display**
- ```rust
fn fmt(self: &Self, fmt: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
```
- **Eq**
- **Error**
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- ```rust
fn from(src: SendError<T>) -> TrySendError<T> { /* ... */ }
```
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **PartialEq**
- ```rust
fn eq(self: &Self, other: &TrySendError<T>) -> bool { /* ... */ }
```
- **RefUnwindSafe**
- **Send**
- **StructuralPartialEq**
- **Sync**
- **ToOwned**
- ```rust
fn to_owned(self: &Self) -> T { /* ... */ }
```
- ```rust
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
```
- **ToString**
- ```rust
fn to_string(self: &Self) -> String { /* ... */ }
```
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Enum `TryRecvError`
Error returned by `try_recv`.
```rust
pub enum TryRecvError {
Empty,
Disconnected,
}
```
##### Variants
###### `Empty`
This **channel** is currently empty, but the **Sender**(s) have not yet
disconnected, so data may yet become available.
###### `Disconnected`
The **channel**'s sending half has become disconnected, and there will
never be any more data received on it.
##### Implementations
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Clone**
- ```rust
fn clone(self: &Self) -> TryRecvError { /* ... */ }
```
- **CloneToUninit**
- ```rust
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
```
- **Copy**
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Display**
- ```rust
fn fmt(self: &Self, fmt: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
```
- **Eq**
- **Error**
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **PartialEq**
- ```rust
fn eq(self: &Self, other: &TryRecvError) -> bool { /* ... */ }
```
- **RefUnwindSafe**
- **Send**
- **StructuralPartialEq**
- **Sync**
- **ToOwned**
- ```rust
fn to_owned(self: &Self) -> T { /* ... */ }
```
- ```rust
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
```
- **ToString**
- ```rust
fn to_string(self: &Self) -> String { /* ... */ }
```
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Enum `SendTimeoutError`
**Attributes:**
- `Other("#[<cfg>(feature = \"time\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"time\")))]")`
- `Other("#[doc(cfg(feature = \"time\"))]")`
Error returned by [`Sender::send_timeout`](super::Sender::send_timeout)].
```rust
pub enum SendTimeoutError<T> {
Timeout(T),
Closed(T),
}
```
##### Variants
###### `Timeout`
The data could not be sent on the channel because the channel is
full, and the timeout to send has elapsed.
Fields:
| Index | Type | Documentation |
|-------|------|---------------|
| 0 | `T` | |
###### `Closed`
The receive half of the channel was explicitly closed or has been
dropped.
Fields:
| Index | Type | Documentation |
|-------|------|---------------|
| 0 | `T` | |
##### Implementations
###### Methods
- ```rust
pub fn into_inner(self: Self) -> T { /* ... */ }
```
Consume the `SendTimeoutError`, returning the unsent value.
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Clone**
- ```rust
fn clone(self: &Self) -> SendTimeoutError<T> { /* ... */ }
```
- **CloneToUninit**
- ```rust
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
```
- **Copy**
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
```
- **Display**
- ```rust
fn fmt(self: &Self, fmt: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
```
- **Eq**
- **Error**
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **PartialEq**
- ```rust
fn eq(self: &Self, other: &SendTimeoutError<T>) -> bool { /* ... */ }
```
- **RefUnwindSafe**
- **Send**
- **StructuralPartialEq**
- **Sync**
- **ToOwned**
- ```rust
fn to_owned(self: &Self) -> T { /* ... */ }
```
- ```rust
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
```
- **ToString**
- ```rust
fn to_string(self: &Self) -> String { /* ... */ }
```
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
### Re-exports
#### Re-export `channel`
```rust
pub use self::bounded::channel;
```
#### Re-export `OwnedPermit`
```rust
pub use self::bounded::OwnedPermit;
```
#### Re-export `Permit`
```rust
pub use self::bounded::Permit;
```
#### Re-export `PermitIterator`
```rust
pub use self::bounded::PermitIterator;
```
#### Re-export `Receiver`
```rust
pub use self::bounded::Receiver;
```
#### Re-export `Sender`
```rust
pub use self::bounded::Sender;
```
#### Re-export `WeakSender`
```rust
pub use self::bounded::WeakSender;
```
#### Re-export `unbounded_channel`
```rust
pub use self::unbounded::unbounded_channel;
```
#### Re-export `UnboundedReceiver`
```rust
pub use self::unbounded::UnboundedReceiver;
```
#### Re-export `UnboundedSender`
```rust
pub use self::unbounded::UnboundedSender;
```
#### Re-export `WeakUnboundedSender`
```rust
pub use self::unbounded::WeakUnboundedSender;
```
## Module `oneshot`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
- `Other("#[<cfg_attr>(not(feature = \"sync\"), allow(dead_code, unreachable_pub))]")`
A one-shot channel is used for sending a single message between
asynchronous tasks. The [`channel`] function is used to create a
[`Sender`] and [`Receiver`] handle pair that form the channel.
The `Sender` handle is used by the producer to send the value.
The `Receiver` handle is used by the consumer to receive the value.
Each handle can be used on separate tasks.
Since the `send` method is not async, it can be used anywhere. This includes
sending between two runtimes, and using it from non-async code.
If the [`Receiver`] is closed before receiving a message which has already
been sent, the message will remain in the channel until the receiver is
dropped, at which point the message will be dropped immediately.
# Examples
```
use tokio::sync::oneshot;
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let (tx, rx) = oneshot::channel();
tokio::spawn(async move {
if let Err(_) = tx.send(3) {
println!("the receiver dropped");
}
});
match rx.await {
Ok(v) => println!("got = {:?}", v),
Err(_) => println!("the sender dropped"),
}
# }
```
If the sender is dropped without sending, the receiver will fail with
[`error::RecvError`]:
```
use tokio::sync::oneshot;
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let (tx, rx) = oneshot::channel::<u32>();
tokio::spawn(async move {
drop(tx);
});
match rx.await {
Ok(_) => panic!("This doesn't happen"),
Err(_) => println!("the sender dropped"),
}
# }
```
To use a `oneshot` channel in a `tokio::select!` loop, add `&mut` in front of
the channel.
```
use tokio::sync::oneshot;
use tokio::time::{interval, sleep, Duration};
# #[tokio::main(flavor = "current_thread")]
# async fn _doc() {}
# #[tokio::main(flavor = "current_thread", start_paused = true)]
# async fn main() {
let (send, mut recv) = oneshot::channel();
let mut interval = interval(Duration::from_millis(100));
# let handle =
tokio::spawn(async move {
sleep(Duration::from_secs(1)).await;
send.send("shut down").unwrap();
});
loop {
tokio::select! {
_ = interval.tick() => println!("Another 100ms"),
msg = &mut recv => {
println!("Got message: {}", msg.unwrap());
break;
}
}
}
# handle.await.unwrap();
# }
```
To use a `Sender` from a destructor, put it in an [`Option`] and call
[`Option::take`].
```
use tokio::sync::oneshot;
struct SendOnDrop {
sender: Option<oneshot::Sender<&'static str>>,
}
impl Drop for SendOnDrop {
fn drop(&mut self) {
if let Some(sender) = self.sender.take() {
// Using `let _ =` to ignore send errors.
let _ = sender.send("I got dropped!");
}
}
}
# #[tokio::main(flavor = "current_thread")]
# async fn _doc() {}
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let (send, recv) = oneshot::channel();
let send_on_drop = SendOnDrop { sender: Some(send) };
drop(send_on_drop);
assert_eq!(recv.await, Ok("I got dropped!"));
# }
```
```rust
pub mod oneshot { /* ... */ }
```
### Modules
## Module `error`
`Oneshot` error types.
```rust
pub mod error { /* ... */ }
```
### Types
#### Struct `RecvError`
Error returned by the `Future` implementation for `Receiver`.
This error is returned by the receiver when the sender is dropped without sending.
```rust
pub struct RecvError(/* private field */);
```
##### Fields
| Index | Type | Documentation |
|-------|------|---------------|
| 0 | `private` | *Private field* |
##### Implementations
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Clone**
- ```rust
fn clone(self: &Self) -> RecvError { /* ... */ }
```
- **CloneToUninit**
- ```rust
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Display**
- ```rust
fn fmt(self: &Self, fmt: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
```
- **Eq**
- **Error**
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **PartialEq**
- ```rust
fn eq(self: &Self, other: &RecvError) -> bool { /* ... */ }
```
- **RefUnwindSafe**
- **Send**
- **StructuralPartialEq**
- **Sync**
- **ToOwned**
- ```rust
fn to_owned(self: &Self) -> T { /* ... */ }
```
- ```rust
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
```
- **ToString**
- ```rust
fn to_string(self: &Self) -> String { /* ... */ }
```
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Enum `TryRecvError`
Error returned by the `try_recv` function on `Receiver`.
```rust
pub enum TryRecvError {
Empty,
Closed,
}
```
##### Variants
###### `Empty`
The send half of the channel has not yet sent a value.
###### `Closed`
The send half of the channel was dropped without sending a value.
##### Implementations
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Clone**
- ```rust
fn clone(self: &Self) -> TryRecvError { /* ... */ }
```
- **CloneToUninit**
- ```rust
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Display**
- ```rust
fn fmt(self: &Self, fmt: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
```
- **Eq**
- **Error**
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **PartialEq**
- ```rust
fn eq(self: &Self, other: &TryRecvError) -> bool { /* ... */ }
```
- **RefUnwindSafe**
- **Send**
- **StructuralPartialEq**
- **Sync**
- **ToOwned**
- ```rust
fn to_owned(self: &Self) -> T { /* ... */ }
```
- ```rust
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
```
- **ToString**
- ```rust
fn to_string(self: &Self) -> String { /* ... */ }
```
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
### Types
#### Struct `Sender`
Sends a value to the associated [`Receiver`].
A pair of both a [`Sender`] and a [`Receiver`] are created by the
[`channel`](fn@channel) function.
# Examples
```
use tokio::sync::oneshot;
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let (tx, rx) = oneshot::channel();
tokio::spawn(async move {
if let Err(_) = tx.send(3) {
println!("the receiver dropped");
}
});
match rx.await {
Ok(v) => println!("got = {:?}", v),
Err(_) => println!("the sender dropped"),
}
# }
```
If the sender is dropped without sending, the receiver will fail with
[`error::RecvError`]:
```
use tokio::sync::oneshot;
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let (tx, rx) = oneshot::channel::<u32>();
tokio::spawn(async move {
drop(tx);
});
match rx.await {
Ok(_) => panic!("This doesn't happen"),
Err(_) => println!("the sender dropped"),
}
# }
```
To use a `Sender` from a destructor, put it in an [`Option`] and call
[`Option::take`].
```
use tokio::sync::oneshot;
struct SendOnDrop {
sender: Option<oneshot::Sender<&'static str>>,
}
impl Drop for SendOnDrop {
fn drop(&mut self) {
if let Some(sender) = self.sender.take() {
// Using `let _ =` to ignore send errors.
let _ = sender.send("I got dropped!");
}
}
}
# #[tokio::main(flavor = "current_thread")]
# async fn _doc() {}
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let (send, recv) = oneshot::channel();
let send_on_drop = SendOnDrop { sender: Some(send) };
drop(send_on_drop);
assert_eq!(recv.await, Ok("I got dropped!"));
# }
```
[`Option`]: std::option::Option
[`Option::take`]: std::option::Option::take
```rust
pub struct Sender<T> {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub fn send(self: Self, t: T) -> Result<(), T> { /* ... */ }
```
Attempts to send a value on this channel, returning it back if it could
- ```rust
pub async fn closed(self: &mut Self) { /* ... */ }
```
Waits for the associated [`Receiver`] handle to close.
- ```rust
pub fn is_closed(self: &Self) -> bool { /* ... */ }
```
Returns `true` if the associated [`Receiver`] handle has been dropped.
- ```rust
pub fn poll_closed(self: &mut Self, cx: &mut Context<''_>) -> Poll<()> { /* ... */ }
```
Checks whether the `oneshot` channel has been closed, and if not, schedules the
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Drop**
- ```rust
fn drop(self: &mut Self) { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `Receiver`
Receives a value from the associated [`Sender`].
A pair of both a [`Sender`] and a [`Receiver`] are created by the
[`channel`](fn@channel) function.
This channel has no `recv` method because the receiver itself implements the
[`Future`] trait. To receive a `Result<T, `[`error::RecvError`]`>`, `.await` the `Receiver` object directly.
The `poll` method on the `Future` trait is allowed to spuriously return
`Poll::Pending` even if the message has been sent. If such a spurious
failure happens, then the caller will be woken when the spurious failure has
been resolved so that the caller can attempt to receive the message again.
Note that receiving such a wakeup does not guarantee that the next call will
succeed — it could fail with another spurious failure. (A spurious failure
does not mean that the message is lost. It is just delayed.)
[`Future`]: trait@std::future::Future
# Examples
```
use tokio::sync::oneshot;
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let (tx, rx) = oneshot::channel();
tokio::spawn(async move {
if let Err(_) = tx.send(3) {
println!("the receiver dropped");
}
});
match rx.await {
Ok(v) => println!("got = {:?}", v),
Err(_) => println!("the sender dropped"),
}
# }
```
If the sender is dropped without sending, the receiver will fail with
[`error::RecvError`]:
```
use tokio::sync::oneshot;
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let (tx, rx) = oneshot::channel::<u32>();
tokio::spawn(async move {
drop(tx);
});
match rx.await {
Ok(_) => panic!("This doesn't happen"),
Err(_) => println!("the sender dropped"),
}
# }
```
To use a `Receiver` in a `tokio::select!` loop, add `&mut` in front of the
channel.
```
use tokio::sync::oneshot;
use tokio::time::{interval, sleep, Duration};
# #[tokio::main(flavor = "current_thread")]
# async fn _doc() {}
# #[tokio::main(flavor = "current_thread", start_paused = true)]
# async fn main() {
let (send, mut recv) = oneshot::channel();
let mut interval = interval(Duration::from_millis(100));
# let handle =
tokio::spawn(async move {
sleep(Duration::from_secs(1)).await;
send.send("shut down").unwrap();
});
loop {
tokio::select! {
_ = interval.tick() => println!("Another 100ms"),
msg = &mut recv => {
println!("Got message: {}", msg.unwrap());
break;
}
}
}
# handle.await.unwrap();
# }
```
```rust
pub struct Receiver<T> {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub fn close(self: &mut Self) { /* ... */ }
```
Prevents the associated [`Sender`] handle from sending a value.
- ```rust
pub fn is_terminated(self: &Self) -> bool { /* ... */ }
```
Checks if this receiver is terminated.
- ```rust
pub fn is_empty(self: &Self) -> bool { /* ... */ }
```
Checks if a channel is empty.
- ```rust
pub fn try_recv(self: &mut Self) -> Result<T, TryRecvError> { /* ... */ }
```
Attempts to receive a value.
- ```rust
pub fn blocking_recv(self: Self) -> Result<T, RecvError> { /* ... */ }
```
Blocking receive to call outside of asynchronous contexts.
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Drop**
- ```rust
fn drop(self: &mut Self) { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Future**
- ```rust
fn poll(self: Pin<&mut Self>, cx: &mut Context<''_>) -> Poll<<Self as >::Output> { /* ... */ }
```
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **IntoFuture**
- ```rust
fn into_future(self: Self) -> <F as IntoFuture>::IntoFuture { /* ... */ }
```
- **RefUnwindSafe**
- **Send**
- **Sync**
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
### Functions
#### Function `channel`
**Attributes:**
- `Other("#[attr = TrackCaller]")`
Creates a new one-shot channel for sending single values across asynchronous
tasks.
The function returns separate "send" and "receive" handles. The `Sender`
handle is used by the producer to send the value. The `Receiver` handle is
used by the consumer to receive the value.
Each handle can be used on separate tasks.
# Examples
```
use tokio::sync::oneshot;
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let (tx, rx) = oneshot::channel();
tokio::spawn(async move {
if let Err(_) = tx.send(3) {
println!("the receiver dropped");
}
});
match rx.await {
Ok(v) => println!("got = {:?}", v),
Err(_) => println!("the sender dropped"),
}
# }
```
```rust
pub fn channel<T>() -> (Sender<T>, Receiver<T>) { /* ... */ }
```
## Module `watch`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
- `Other("#[<cfg_attr>(not(feature = \"sync\"), allow(dead_code, unreachable_pub))]")`
A multi-producer, multi-consumer channel that only retains the *last* sent
value.
This channel is useful for watching for changes to a value from multiple
points in the code base, for example, changes to configuration values.
# Usage
[`channel`] returns a [`Sender`] / [`Receiver`] pair. These are the producer
and consumer halves of the channel. The channel is created with an initial
value.
Each [`Receiver`] independently tracks the last value *seen* by its caller.
To access the **current** value stored in the channel and mark it as *seen*
by a given [`Receiver`], use [`Receiver::borrow_and_update()`].
To access the current value **without** marking it as *seen*, use
[`Receiver::borrow()`]. (If the value has already been marked *seen*,
[`Receiver::borrow()`] is equivalent to [`Receiver::borrow_and_update()`].)
For more information on when to use these methods, see
[here](#borrow_and_update-versus-borrow).
## Change notifications
The [`Receiver`] half provides an asynchronous [`changed`] method. This
method is ready when a new, *unseen* value is sent via the [`Sender`] half.
* [`Receiver::changed()`] returns:
* `Ok(())` on receiving a new value.
* `Err(`[`RecvError`](error::RecvError)`)` if the
channel has been closed __AND__ the current value is *seen*.
* If the current value is *unseen* when calling [`changed`], then
[`changed`] will return immediately. If the current value is *seen*, then
it will sleep until either a new message is sent via the [`Sender`] half,
or the [`Sender`] is dropped.
* On completion, the [`changed`] method marks the new value as *seen*.
* At creation, the initial value is considered *seen*. In other words,
[`Receiver::changed()`] will not return until a subsequent value is sent.
* New [`Receiver`] instances can be created with [`Sender::subscribe()`].
The current value at the time the [`Receiver`] is created is considered
*seen*.
## [`changed`] versus [`has_changed`]
The [`Receiver`] half provides two methods for checking for changes
in the channel, [`has_changed`] and [`changed`].
* [`has_changed`] is a *synchronous* method that checks whether the current
value is seen or not and returns a boolean. This method does __not__ mark the
value as seen.
* [`changed`] is an *asynchronous* method that will return once an unseen
value is in the channel. This method does mark the value as seen.
Note there are two behavioral differences on when these two methods return
an error.
- [`has_changed`] errors if and only if the channel is closed.
- [`changed`] errors if the channel has been closed __AND__
the current value is seen.
See the example below that shows how these methods have different fallibility.
## [`borrow_and_update`] versus [`borrow`]
If the receiver intends to await notifications from [`changed`] in a loop,
[`Receiver::borrow_and_update()`] should be preferred over
[`Receiver::borrow()`]. This avoids a potential race where a new value is
sent between [`changed`] being ready and the value being read. (If
[`Receiver::borrow()`] is used, the loop may run twice with the same value.)
If the receiver is only interested in the current value, and does not intend
to wait for changes, then [`Receiver::borrow()`] can be used. It may be more
convenient to use [`borrow`](Receiver::borrow) since it's an `&self`
method---[`borrow_and_update`](Receiver::borrow_and_update) requires `&mut
self`.
# Examples
The following example prints `hello! world! `.
```
use tokio::sync::watch;
use tokio::time::{Duration, sleep};
# async fn dox() -> Result<(), Box<dyn std::error::Error>> {
let (tx, mut rx) = watch::channel("hello");
tokio::spawn(async move {
// Use the equivalent of a "do-while" loop so the initial value is
// processed before awaiting the `changed()` future.
loop {
println!("{}! ", *rx.borrow_and_update());
if rx.changed().await.is_err() {
break;
}
}
});
sleep(Duration::from_millis(100)).await;
tx.send("world")?;
# Ok(())
# }
```
Difference on fallibility of [`changed`] versus [`has_changed`].
```
use tokio::sync::watch;
#[tokio::main(flavor = "current_thread")]
# async fn main() {
let (tx, mut rx) = watch::channel("hello");
tx.send("goodbye").unwrap();
drop(tx);
// `has_changed` does not mark the value as seen and errors
// since the channel is closed.
assert!(rx.has_changed().is_err());
// `changed` returns Ok since the value is not already marked as seen
// even if the channel is closed.
assert!(rx.changed().await.is_ok());
// The `changed` call above marks the value as seen.
// The next `changed` call now returns an error as the channel is closed
// AND the current value is seen.
assert!(rx.changed().await.is_err());
# }
```
# Closing
[`Sender::is_closed`] and [`Sender::closed`] allow the producer to detect
when all [`Receiver`] handles have been dropped. This indicates that there
is no further interest in the values being produced and work can be stopped.
The value in the channel will not be dropped until all senders and all
receivers have been dropped.
# Thread safety
Both [`Sender`] and [`Receiver`] are thread safe. They can be moved to other
threads and can be used in a concurrent environment. Clones of [`Receiver`]
handles may be moved to separate threads and also used concurrently.
[`Sender`]: crate::sync::watch::Sender
[`Receiver`]: crate::sync::watch::Receiver
[`changed`]: crate::sync::watch::Receiver::changed
[`has_changed`]: crate::sync::watch::Receiver::has_changed
[`borrow`]: crate::sync::watch::Receiver::borrow
[`borrow_and_update`]: crate::sync::watch::Receiver::borrow_and_update
[`Receiver::changed()`]: crate::sync::watch::Receiver::changed
[`Receiver::borrow()`]: crate::sync::watch::Receiver::borrow
[`Receiver::borrow_and_update()`]:
crate::sync::watch::Receiver::borrow_and_update
[`channel`]: crate::sync::watch::channel
[`Sender::is_closed`]: crate::sync::watch::Sender::is_closed
[`Sender::closed`]: crate::sync::watch::Sender::closed
[`Sender::subscribe()`]: crate::sync::watch::Sender::subscribe
```rust
pub mod watch { /* ... */ }
```
### Modules
## Module `error`
Watch error types.
```rust
pub mod error { /* ... */ }
```
### Types
#### Struct `SendError`
Error produced when sending a value fails.
```rust
pub struct SendError<T>(pub T);
```
##### Fields
| Index | Type | Documentation |
|-------|------|---------------|
| 0 | `T` | |
##### Implementations
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Clone**
- ```rust
fn clone(self: &Self) -> SendError<T> { /* ... */ }
```
- **CloneToUninit**
- ```rust
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
```
- **Copy**
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
```
- **Display**
- ```rust
fn fmt(self: &Self, fmt: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
```
- **Eq**
- **Error**
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **PartialEq**
- ```rust
fn eq(self: &Self, other: &SendError<T>) -> bool { /* ... */ }
```
- **RefUnwindSafe**
- **Send**
- **StructuralPartialEq**
- **Sync**
- **ToOwned**
- ```rust
fn to_owned(self: &Self) -> T { /* ... */ }
```
- ```rust
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
```
- **ToString**
- ```rust
fn to_string(self: &Self) -> String { /* ... */ }
```
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `RecvError`
Error produced when receiving a change notification.
```rust
pub struct RecvError(/* private field */);
```
##### Fields
| Index | Type | Documentation |
|-------|------|---------------|
| 0 | `private` | *Private field* |
##### Implementations
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Clone**
- ```rust
fn clone(self: &Self) -> RecvError { /* ... */ }
```
- **CloneToUninit**
- ```rust
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Display**
- ```rust
fn fmt(self: &Self, fmt: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
```
- **Error**
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **ToOwned**
- ```rust
fn to_owned(self: &Self) -> T { /* ... */ }
```
- ```rust
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
```
- **ToString**
- ```rust
fn to_string(self: &Self) -> String { /* ... */ }
```
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
### Types
#### Struct `Receiver`
Receives values from the associated [`Sender`](struct@Sender).
Instances are created by the [`channel`](fn@channel) function.
To turn this receiver into a `Stream`, you can use the [`WatchStream`]
wrapper.
[`WatchStream`]: https://docs.rs/tokio-stream/0.1/tokio_stream/wrappers/struct.WatchStream.html
```rust
pub struct Receiver<T> {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub fn borrow(self: &Self) -> Ref<''_, T> { /* ... */ }
```
Returns a reference to the most recently sent value.
- ```rust
pub fn borrow_and_update(self: &mut Self) -> Ref<''_, T> { /* ... */ }
```
Returns a reference to the most recently sent value and marks that value
- ```rust
pub fn has_changed(self: &Self) -> Result<bool, error::RecvError> { /* ... */ }
```
Checks if this channel contains a message that this receiver has not yet
- ```rust
pub fn mark_changed(self: &mut Self) { /* ... */ }
```
Marks the state as changed.
- ```rust
pub fn mark_unchanged(self: &mut Self) { /* ... */ }
```
Marks the state as unchanged.
- ```rust
pub async fn changed(self: &mut Self) -> Result<(), error::RecvError> { /* ... */ }
```
Waits for a change notification, then marks the current value as seen.
- ```rust
pub async fn wait_for</* synthetic */ impl FnMut(&T) -> bool: FnMut(&T) -> bool>(self: &mut Self, f: impl FnMut(&T) -> bool) -> Result<Ref<''_, T>, error::RecvError> { /* ... */ }
```
Waits for a value that satisfies the provided condition.
- ```rust
pub fn same_channel(self: &Self, other: &Self) -> bool { /* ... */ }
```
Returns `true` if receivers belong to the same channel.
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Clone**
- ```rust
fn clone(self: &Self) -> Self { /* ... */ }
```
- **CloneToUninit**
- ```rust
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Drop**
- ```rust
fn drop(self: &mut Self) { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **ToOwned**
- ```rust
fn to_owned(self: &Self) -> T { /* ... */ }
```
- ```rust
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
```
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `Sender`
Sends values to the associated [`Receiver`](struct@Receiver).
Instances are created by the [`channel`](fn@channel) function.
```rust
pub struct Sender<T> {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub fn new(init: T) -> Self { /* ... */ }
```
Creates the sending-half of the [`watch`] channel.
- ```rust
pub fn send(self: &Self, value: T) -> Result<(), error::SendError<T>> { /* ... */ }
```
Sends a new value via the channel, notifying all receivers.
- ```rust
pub fn send_modify<F>(self: &Self, modify: F)
where
F: FnOnce(&mut T) { /* ... */ }
```
Modifies the watched value **unconditionally** in-place,
- ```rust
pub fn send_if_modified<F>(self: &Self, modify: F) -> bool
where
F: FnOnce(&mut T) -> bool { /* ... */ }
```
Modifies the watched value **conditionally** in-place,
- ```rust
pub fn send_replace(self: &Self, value: T) -> T { /* ... */ }
```
Sends a new value via the channel, notifying all receivers and returning
- ```rust
pub fn borrow(self: &Self) -> Ref<''_, T> { /* ... */ }
```
Returns a reference to the most recently sent value
- ```rust
pub fn is_closed(self: &Self) -> bool { /* ... */ }
```
Checks if the channel has been closed. This happens when all receivers
- ```rust
pub async fn closed(self: &Self) { /* ... */ }
```
Completes when all receivers have dropped.
- ```rust
pub fn subscribe(self: &Self) -> Receiver<T> { /* ... */ }
```
Creates a new [`Receiver`] connected to this `Sender`.
- ```rust
pub fn receiver_count(self: &Self) -> usize { /* ... */ }
```
Returns the number of receivers that currently exist.
- ```rust
pub fn sender_count(self: &Self) -> usize { /* ... */ }
```
Returns the number of senders that currently exist.
- ```rust
pub fn same_channel(self: &Self, other: &Self) -> bool { /* ... */ }
```
Returns `true` if senders belong to the same channel.
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Clone**
- ```rust
fn clone(self: &Self) -> Self { /* ... */ }
```
- **CloneToUninit**
- ```rust
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Default**
- ```rust
fn default() -> Self { /* ... */ }
```
- **Drop**
- ```rust
fn drop(self: &mut Self) { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **ToOwned**
- ```rust
fn to_owned(self: &Self) -> T { /* ... */ }
```
- ```rust
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
```
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `Ref`
Returns a reference to the inner value.
Outstanding borrows hold a read lock on the inner value. This means that
long-lived borrows could cause the producer half to block. It is recommended
to keep the borrow as short-lived as possible. Additionally, if you are
running in an environment that allows `!Send` futures, you must ensure that
the returned `Ref` type is never held alive across an `.await` point,
otherwise, it can lead to a deadlock.
The priority policy of the lock is dependent on the underlying lock
implementation, and this type does not guarantee that any particular policy
will be used. In particular, a producer which is waiting to acquire the lock
in `send` might or might not block concurrent calls to `borrow`, e.g.:
<details><summary>Potential deadlock example</summary>
```text
// Task 1 (on thread A) | // Task 2 (on thread B)
let _ref1 = rx.borrow(); |
| // will block
| let _ = tx.send(());
// may deadlock |
let _ref2 = rx.borrow(); |
```
</details>
```rust
pub struct Ref<''a, T> {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub fn has_changed(self: &Self) -> bool { /* ... */ }
```
Indicates if the borrowed value is considered as _changed_ since the last
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Deref**
- ```rust
fn deref(self: &Self) -> &T { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **Receiver**
- **RefUnwindSafe**
- **Send**
- **Sync**
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
### Functions
#### Function `channel`
Creates a new watch channel, returning the "send" and "receive" handles.
All values sent by [`Sender`] will become visible to the [`Receiver`] handles.
Only the last value sent is made available to the [`Receiver`] half. All
intermediate values are dropped.
# Examples
The following example prints `hello! world! `.
```
use tokio::sync::watch;
use tokio::time::{Duration, sleep};
# async fn dox() -> Result<(), Box<dyn std::error::Error>> {
let (tx, mut rx) = watch::channel("hello");
tokio::spawn(async move {
// Use the equivalent of a "do-while" loop so the initial value is
// processed before awaiting the `changed()` future.
loop {
println!("{}! ", *rx.borrow_and_update());
if rx.changed().await.is_err() {
break;
}
}
});
sleep(Duration::from_millis(100)).await;
tx.send("world")?;
# Ok(())
# }
```
[`Sender`]: struct@Sender
[`Receiver`]: struct@Receiver
```rust
pub fn channel<T>(init: T) -> (Sender<T>, Receiver<T>) { /* ... */ }
```
### Re-exports
#### Re-export `Barrier`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
```rust
pub use barrier::Barrier;
```
#### Re-export `BarrierWaitResult`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
```rust
pub use barrier::BarrierWaitResult;
```
#### Re-export `Mutex`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
```rust
pub use mutex::Mutex;
```
#### Re-export `MutexGuard`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
```rust
pub use mutex::MutexGuard;
```
#### Re-export `TryLockError`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
```rust
pub use mutex::TryLockError;
```
#### Re-export `OwnedMutexGuard`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
```rust
pub use mutex::OwnedMutexGuard;
```
#### Re-export `MappedMutexGuard`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
```rust
pub use mutex::MappedMutexGuard;
```
#### Re-export `OwnedMappedMutexGuard`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
```rust
pub use mutex::OwnedMappedMutexGuard;
```
#### Re-export `Notify`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
```rust
pub use notify::Notify;
```
#### Re-export `AcquireError`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
```rust
pub use batch_semaphore::AcquireError;
```
#### Re-export `TryAcquireError`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
```rust
pub use batch_semaphore::TryAcquireError;
```
#### Re-export `Semaphore`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
```rust
pub use semaphore::Semaphore;
```
#### Re-export `SemaphorePermit`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
```rust
pub use semaphore::SemaphorePermit;
```
#### Re-export `OwnedSemaphorePermit`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
```rust
pub use semaphore::OwnedSemaphorePermit;
```
#### Re-export `RwLock`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
```rust
pub use rwlock::RwLock;
```
#### Re-export `OwnedRwLockReadGuard`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
```rust
pub use rwlock::owned_read_guard::OwnedRwLockReadGuard;
```
#### Re-export `OwnedRwLockWriteGuard`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
```rust
pub use rwlock::owned_write_guard::OwnedRwLockWriteGuard;
```
#### Re-export `OwnedRwLockMappedWriteGuard`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
```rust
pub use rwlock::owned_write_guard_mapped::OwnedRwLockMappedWriteGuard;
```
#### Re-export `RwLockReadGuard`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
```rust
pub use rwlock::read_guard::RwLockReadGuard;
```
#### Re-export `RwLockWriteGuard`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
```rust
pub use rwlock::write_guard::RwLockWriteGuard;
```
#### Re-export `RwLockMappedWriteGuard`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
```rust
pub use rwlock::write_guard_mapped::RwLockMappedWriteGuard;
```
#### Re-export `OnceCell`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
```rust
pub use self::once_cell::OnceCell;
```
#### Re-export `SetError`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
```rust
pub use self::once_cell::SetError;
```
#### Re-export `SetOnce`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
```rust
pub use self::set_once::SetOnce;
```
#### Re-export `SetOnceError`
**Attributes:**
- `Other("#[<cfg>(feature = \"sync\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"sync\")))]")`
- `Other("#[doc(cfg(feature = \"sync\"))]")`
```rust
pub use self::set_once::SetOnceError;
```
## Module `task`
Asynchronous green-threads.
## What are Tasks?
A _task_ is a light weight, non-blocking unit of execution. A task is similar
to an OS thread, but rather than being managed by the OS scheduler, they are
managed by the [Tokio runtime][rt]. Another name for this general pattern is
[green threads]. If you are familiar with [Go's goroutines], [Kotlin's
coroutines], or [Erlang's processes], you can think of Tokio's tasks as
something similar.
Key points about tasks include:
* Tasks are **light weight**. Because tasks are scheduled by the Tokio
runtime rather than the operating system, creating new tasks or switching
between tasks does not require a context switch and has fairly low
overhead. Creating, running, and destroying large numbers of tasks is
quite cheap, especially compared to OS threads.
* Tasks are scheduled **cooperatively**. Most operating systems implement
_preemptive multitasking_. This is a scheduling technique where the
operating system allows each thread to run for a period of time, and then
_preempts_ it, temporarily pausing that thread and switching to another.
Tasks, on the other hand, implement _cooperative multitasking_. In
cooperative multitasking, a task is allowed to run until it _yields_,
indicating to the Tokio runtime's scheduler that it cannot currently
continue executing. When a task yields, the Tokio runtime switches to
executing the next task.
* Tasks are **non-blocking**. Typically, when an OS thread performs I/O or
must synchronize with another thread, it _blocks_, allowing the OS to
schedule another thread. When a task cannot continue executing, it must
yield instead, allowing the Tokio runtime to schedule another task. Tasks
should generally not perform system calls or other operations that could
block a thread, as this would prevent other tasks running on the same
thread from executing as well. Instead, this module provides APIs for
running blocking operations in an asynchronous context.
[rt]: crate::runtime
[green threads]: https://en.wikipedia.org/wiki/Green_threads
[Go's goroutines]: https://tour.golang.org/concurrency/1
[Kotlin's coroutines]: https://kotlinlang.org/docs/reference/coroutines-overview.html
[Erlang's processes]: http://erlang.org/doc/getting_started/conc_prog.html#processes
## Working with Tasks
This module provides the following APIs for working with tasks:
### Spawning
Perhaps the most important function in this module is [`task::spawn`]. This
function can be thought of as an async equivalent to the standard library's
[`thread::spawn`][`std::thread::spawn`]. It takes an `async` block or other
[future], and creates a new task to run that work concurrently:
```
use tokio::task;
# async fn doc() {
task::spawn(async {
// perform some work here...
});
# }
```
Like [`std::thread::spawn`], `task::spawn` returns a [`JoinHandle`] struct.
A `JoinHandle` is itself a future which may be used to await the output of
the spawned task. For example:
```
use tokio::task;
# #[tokio::main(flavor = "current_thread")]
# async fn main() -> Result<(), Box<dyn std::error::Error>> {
let join = task::spawn(async {
// ...
"hello world!"
});
// ...
// Await the result of the spawned task.
let result = join.await?;
assert_eq!(result, "hello world!");
# Ok(())
# }
```
Again, like `std::thread`'s [`JoinHandle` type][thread_join], if the spawned
task panics, awaiting its `JoinHandle` will return a [`JoinError`]. For
example:
```
# #[cfg(not(target_family = "wasm"))]
# {
use tokio::task;
# #[tokio::main] async fn main() {
let join = task::spawn(async {
panic!("something bad happened!")
});
// The returned result indicates that the task failed.
assert!(join.await.is_err());
# }
# }
```
`spawn`, `JoinHandle`, and `JoinError` are present when the "rt"
feature flag is enabled.
[`task::spawn`]: crate::task::spawn()
[future]: std::future::Future
[`std::thread::spawn`]: std::thread::spawn
[`JoinHandle`]: crate::task::JoinHandle
[thread_join]: std::thread::JoinHandle
[`JoinError`]: crate::task::JoinError
#### Cancellation
Spawned tasks may be cancelled using the [`JoinHandle::abort`] or
[`AbortHandle::abort`] methods. When one of these methods are called, the
task is signalled to shut down next time it yields at an `.await` point. If
the task is already idle, then it will be shut down as soon as possible
without running again before being shut down. Additionally, shutting down a
Tokio runtime (e.g. by returning from `#[tokio::main]`) immediately cancels
all tasks on it.
When tasks are shut down, it will stop running at whichever `.await` it has
yielded at. All local variables are destroyed by running their destructor.
Once shutdown has completed, awaiting the [`JoinHandle`] will fail with a
[cancelled error](crate::task::JoinError::is_cancelled).
Note that aborting a task does not guarantee that it fails with a cancelled
error, since it may complete normally first. For example, if the task does
not yield to the runtime at any point between the call to `abort` and the
end of the task, then the [`JoinHandle`] will instead report that the task
exited normally.
Be aware that tasks spawned using [`spawn_blocking`] cannot be aborted
because they are not async. If you call `abort` on a `spawn_blocking`
task, then this *will not have any effect*, and the task will continue
running normally. The exception is if the task has not started running
yet; in that case, calling `abort` may prevent the task from starting.
Be aware that calls to [`JoinHandle::abort`] just schedule the task for
cancellation, and will return before the cancellation has completed. To wait
for cancellation to complete, wait for the task to finish by awaiting the
[`JoinHandle`]. Similarly, the [`JoinHandle::is_finished`] method does not
return `true` until the cancellation has finished.
Calling [`JoinHandle::abort`] multiple times has the same effect as calling
it once.
Tokio also provides an [`AbortHandle`], which is like the [`JoinHandle`],
except that it does not provide a mechanism to wait for the task to finish.
Each task can only have one [`JoinHandle`], but it can have more than one
[`AbortHandle`].
[`JoinHandle::abort`]: crate::task::JoinHandle::abort
[`AbortHandle::abort`]: crate::task::AbortHandle::abort
[`AbortHandle`]: crate::task::AbortHandle
[`JoinHandle::is_finished`]: crate::task::JoinHandle::is_finished
### Blocking and Yielding
As we discussed above, code running in asynchronous tasks should not perform
operations that can block. A blocking operation performed in a task running
on a thread that is also running other tasks would block the entire thread,
preventing other tasks from running.
Instead, Tokio provides two APIs for running blocking operations in an
asynchronous context: [`task::spawn_blocking`] and [`task::block_in_place`].
Be aware that if you call a non-async method from async code, that non-async
method is still inside the asynchronous context, so you should also avoid
blocking operations there. This includes destructors of objects destroyed in
async code.
#### `spawn_blocking`
The `task::spawn_blocking` function is similar to the `task::spawn` function
discussed in the previous section, but rather than spawning an
_non-blocking_ future on the Tokio runtime, it instead spawns a
_blocking_ function on a dedicated thread pool for blocking tasks. For
example:
```
use tokio::task;
# async fn docs() {
task::spawn_blocking(|| {
// do some compute-heavy work or call synchronous code
});
# }
```
Just like `task::spawn`, `task::spawn_blocking` returns a `JoinHandle`
which we can use to await the result of the blocking operation:
```rust
# use tokio::task;
# async fn docs() -> Result<(), Box<dyn std::error::Error>>{
let join = task::spawn_blocking(|| {
// do some compute-heavy work or call synchronous code
"blocking completed"
});
let result = join.await?;
assert_eq!(result, "blocking completed");
# Ok(())
# }
```
#### `block_in_place`
When using the [multi-threaded runtime][rt-multi-thread], the [`task::block_in_place`]
function is also available. Like `task::spawn_blocking`, this function
allows running a blocking operation from an asynchronous context. Unlike
`spawn_blocking`, however, `block_in_place` works by transitioning the
_current_ worker thread to a blocking thread, moving other tasks running on
that thread to another worker thread. This can improve performance by avoiding
context switches.
For example:
```
# #[cfg(not(target_family = "wasm"))]
# {
use tokio::task;
# async fn docs() {
let result = task::block_in_place(|| {
// do some compute-heavy work or call synchronous code
"blocking completed"
});
assert_eq!(result, "blocking completed");
# }
# }
```
#### `yield_now`
In addition, this module provides a [`task::yield_now`] async function
that is analogous to the standard library's [`thread::yield_now`]. Calling
and `await`ing this function will cause the current task to yield to the
Tokio runtime's scheduler, allowing other tasks to be
scheduled. Eventually, the yielding task will be polled again, allowing it
to execute. For example:
```rust
use tokio::task;
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
async {
task::spawn(async {
// ...
println!("spawned task done!")
});
// Yield, allowing the newly-spawned task to execute first.
task::yield_now().await;
println!("main task done!");
}
# .await;
# }
```
[`task::spawn_blocking`]: crate::task::spawn_blocking
[`task::block_in_place`]: crate::task::block_in_place
[rt-multi-thread]: ../runtime/index.html#threaded-scheduler
[`task::yield_now`]: crate::task::yield_now()
[`thread::yield_now`]: std::thread::yield_now
```rust
pub mod task { /* ... */ }
```
### Modules
## Module `coop`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
- `Other("#[<cfg_attr>(not(feature = \"full\"), allow(dead_code))]")`
- `Other("#[<cfg_attr>(not(feature = \"rt\"), allow(unreachable_pub))]")`
Utilities for improved cooperative scheduling.
### Cooperative scheduling
A single call to [`poll`] on a top-level task may potentially do a lot of
work before it returns `Poll::Pending`. If a task runs for a long period of
time without yielding back to the executor, it can starve other tasks
waiting on that executor to execute them, or drive underlying resources.
Since Rust does not have a runtime, it is difficult to forcibly preempt a
long-running task. Instead, this module provides an opt-in mechanism for
futures to collaborate with the executor to avoid starvation.
Consider a future like this one:
```
# use tokio_stream::{Stream, StreamExt};
async fn drop_all<I: Stream + Unpin>(mut input: I) {
while let Some(_) = input.next().await {}
}
```
It may look harmless, but consider what happens under heavy load if the
input stream is _always_ ready. If we spawn `drop_all`, the task will never
yield, and will starve other tasks and resources on the same executor.
To account for this, Tokio has explicit yield points in a number of library
functions, which force tasks to return to the executor periodically.
#### unconstrained
If necessary, [`task::unconstrained`] lets you opt a future out of Tokio's cooperative
scheduling. When a future is wrapped with `unconstrained`, it will never be forced to yield to
Tokio. For example:
```
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
use tokio::{task, sync::mpsc};
let fut = async {
let (tx, mut rx) = mpsc::unbounded_channel();
for i in 0..1000 {
let _ = tx.send(());
// This will always be ready. If coop was in effect, this code would be forced to yield
// periodically. However, if left unconstrained, then this code will never yield.
rx.recv().await;
}
};
task::coop::unconstrained(fut).await;
# }
```
[`poll`]: method@std::future::Future::poll
[`task::unconstrained`]: crate::task::unconstrained()
```rust
pub mod coop { /* ... */ }
```
### Types
#### Struct `RestoreOnPending`
**Attributes:**
- `Other("#[<cfg>(any(feature = \"fs\", feature = \"io-std\", feature = \"net\", feature =\n\"process\", feature = \"rt\", feature = \"signal\", feature = \"sync\", feature =\n\"time\",))]")`
- `MustUse { reason: None }`
Value returned by the [`poll_proceed`] method.
```rust
pub struct RestoreOnPending(/* private field */, /* private field */);
```
##### Fields
| Index | Type | Documentation |
|-------|------|---------------|
| 0 | `private` | *Private field* |
| 1 | `private` | *Private field* |
##### Implementations
###### Methods
- ```rust
pub fn made_progress(self: &Self) { /* ... */ }
```
Signals that the task that obtained this `RestoreOnPending` was able to make
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Drop**
- ```rust
fn drop(self: &mut Self) { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `Coop`
**Attributes:**
- `MustUse { reason: Some("futures do nothing unless polled") }`
Future wrapper to ensure cooperative scheduling created by [`cooperative`].
```rust
pub struct Coop<F: Future> {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Future**
- ```rust
fn poll(self: Pin<&mut Self>, cx: &mut Context<''_>) -> Poll<<Self as >::Output> { /* ... */ }
```
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **IntoFuture**
- ```rust
fn into_future(self: Self) -> <F as IntoFuture>::IntoFuture { /* ... */ }
```
- **RefUnwindSafe**
- **Send**
- **Sync**
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
### Functions
#### Function `has_budget_remaining`
**Attributes:**
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
- `Other("#[attr = Inline(Always)]")`
Returns `true` if there is still budget left on the task.
# Examples
This example defines a `Timeout` future that requires a given `future` to complete before the
specified duration elapses. If it does, its result is returned; otherwise, an error is returned
and the future is canceled.
Note that the future could exhaust the budget before we evaluate the timeout. Using `has_budget_remaining`,
we can detect this scenario and ensure the timeout is always checked.
```
# use std::future::Future;
# use std::pin::{pin, Pin};
# use std::task::{ready, Context, Poll};
# use tokio::task::coop;
# use tokio::time::Sleep;
pub struct Timeout<T> {
future: T,
delay: Pin<Box<Sleep>>,
}
impl<T> Future for Timeout<T>
where
T: Future + Unpin,
{
type Output = Result<T::Output, ()>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = Pin::into_inner(self);
let future = Pin::new(&mut this.future);
let delay = Pin::new(&mut this.delay);
// check if the future is ready
let had_budget_before = coop::has_budget_remaining();
if let Poll::Ready(v) = future.poll(cx) {
return Poll::Ready(Ok(v));
}
let has_budget_now = coop::has_budget_remaining();
// evaluate the timeout
if let (true, false) = (had_budget_before, has_budget_now) {
// it is the underlying future that exhausted the budget
ready!(pin!(coop::unconstrained(delay)).poll(cx));
} else {
ready!(delay.poll(cx));
}
return Poll::Ready(Err(()));
}
}
```
```rust
pub fn has_budget_remaining() -> bool { /* ... */ }
```
#### Function `poll_proceed`
**Attributes:**
- `Other("#[<cfg>(any(feature = \"fs\", feature = \"io-std\", feature = \"net\", feature =\n\"process\", feature = \"rt\", feature = \"signal\", feature = \"sync\", feature =\n\"time\",))]")`
- `Other("#[attr = Inline(Hint)]")`
Decrements the task budget and returns [`Poll::Pending`] if the budget is depleted.
This indicates that the task should yield to the scheduler. Otherwise, returns
[`RestoreOnPending`] which can be used to commit the budget consumption.
The returned [`RestoreOnPending`] will revert the budget to its former
value when dropped unless [`RestoreOnPending::made_progress`]
is called. It is the caller's responsibility to do so when it _was_ able to
make progress after the call to [`poll_proceed`].
Restoring the budget automatically ensures the task can try to make progress in some other
way.
Note that [`RestoreOnPending`] restores the budget **as it was before [`poll_proceed`]**.
Therefore, if the budget is _further_ adjusted between when [`poll_proceed`] returns and
[`RestoreOnPending`] is dropped, those adjustments are erased unless the caller indicates
that progress was made.
# Examples
This example wraps the `futures::channel::mpsc::UnboundedReceiver` to
cooperate with the Tokio scheduler. Each time a value is received, task budget
is consumed. If no budget is available, the task yields to the scheduler.
```
use std::pin::Pin;
use std::task::{ready, Context, Poll};
use tokio::task::coop;
use futures::stream::{Stream, StreamExt};
use futures::channel::mpsc::UnboundedReceiver;
struct CoopUnboundedReceiver<T> {
receiver: UnboundedReceiver<T>,
}
impl<T> Stream for CoopUnboundedReceiver<T> {
type Item = T;
fn poll_next(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>
) -> Poll<Option<T>> {
let coop = ready!(coop::poll_proceed(cx));
match self.receiver.poll_next_unpin(cx) {
Poll::Ready(v) => {
// We received a value, so consume budget.
coop.made_progress();
Poll::Ready(v)
}
Poll::Pending => Poll::Pending,
}
}
}
```
```rust
pub fn poll_proceed(cx: &mut std::task::Context<''_>) -> std::task::Poll<RestoreOnPending> { /* ... */ }
```
#### Function `cooperative`
**Attributes:**
- `Other("#[<cfg>(any(feature = \"fs\", feature = \"io-std\", feature = \"net\", feature =\n\"process\", feature = \"rt\", feature = \"signal\", feature = \"sync\", feature =\n\"time\",))]")`
- `Other("#[attr = Inline(Hint)]")`
Creates a wrapper future that makes the inner future cooperate with the Tokio scheduler.
When polled, the wrapper will first call [`poll_proceed`] to consume task budget, and
immediately yield if the budget has been depleted. If budget was available, the inner future
is polled. The budget consumption will be made final using [`RestoreOnPending::made_progress`]
if the inner future resolves to its final value.
# Examples
When you call `recv` on the `Receiver` of a [`tokio::sync::mpsc`](crate::sync::mpsc)
channel, task budget will automatically be consumed when the next value is returned.
This makes tasks that use Tokio mpsc channels automatically cooperative.
If you're using [`futures::channel::mpsc`](https://docs.rs/futures/latest/futures/channel/mpsc/index.html)
instead, automatic task budget consumption will not happen. This example shows how can use
`cooperative` to make `futures::channel::mpsc` channels cooperate with the scheduler in the
same way Tokio channels do.
```
use tokio::task::coop::cooperative;
use futures::channel::mpsc::Receiver;
use futures::stream::StreamExt;
async fn receive_next<T>(receiver: &mut Receiver<T>) -> Option<T> {
// Use `StreamExt::next` to obtain a `Future` that resolves to the next value
let recv_future = receiver.next();
// Wrap it a cooperative wrapper
let coop_future = cooperative(recv_future);
// And await
coop_future.await
}
```rust
pub fn cooperative<F: Future>(fut: F) -> Coop<F> { /* ... */ }
```
### Re-exports
#### Re-export `consume_budget`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
```rust
pub use consume_budget::consume_budget;
```
#### Re-export `unconstrained`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
```rust
pub use unconstrained::unconstrained;
```
#### Re-export `Unconstrained`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
```rust
pub use unconstrained::Unconstrained;
```
## Module `join_set`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
- `Other("#[<cfg>(tokio_unstable)]")`
A collection of tasks spawned on a Tokio runtime.
This module provides the [`JoinSet`] type, a collection which stores a set
of spawned tasks and allows asynchronously awaiting the output of those
tasks as they complete. See the documentation for the [`JoinSet`] type for
details.
```rust
pub mod join_set { /* ... */ }
```
### Types
#### Struct `JoinSet`
**Attributes:**
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
A collection of tasks spawned on a Tokio runtime.
A `JoinSet` can be used to await the completion of some or all of the tasks
in the set. The set is not ordered, and the tasks will be returned in the
order they complete.
All of the tasks must have the same return type `T`.
When the `JoinSet` is dropped, all tasks in the `JoinSet` are immediately aborted.
# Examples
Spawn multiple tasks and wait for them.
```
use tokio::task::JoinSet;
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let mut set = JoinSet::new();
for i in 0..10 {
set.spawn(async move { i });
}
let mut seen = [false; 10];
while let Some(res) = set.join_next().await {
let idx = res.unwrap();
seen[idx] = true;
}
for i in 0..10 {
assert!(seen[i]);
}
# }
```
# Task ID guarantees
While a task is tracked in a `JoinSet`, that task's ID is unique relative
to all other running tasks in Tokio. For this purpose, tracking a task in a
`JoinSet` is equivalent to holding a [`JoinHandle`] to it. See the [task ID]
documentation for more info.
[`JoinHandle`]: crate::task::JoinHandle
[task ID]: crate::task::Id
```rust
pub struct JoinSet<T> {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub fn new() -> Self { /* ... */ }
```
Create a new `JoinSet`.
- ```rust
pub fn len(self: &Self) -> usize { /* ... */ }
```
Returns the number of tasks currently in the `JoinSet`.
- ```rust
pub fn is_empty(self: &Self) -> bool { /* ... */ }
```
Returns whether the `JoinSet` is empty.
- ```rust
pub fn build_task(self: &mut Self) -> Builder<''_, T> { /* ... */ }
```
Returns a [`Builder`] that can be used to configure a task prior to
- ```rust
pub fn spawn<F>(self: &mut Self, task: F) -> AbortHandle
where
F: Future<Output = T> + Send + ''static,
T: Send { /* ... */ }
```
Spawn the provided task on the `JoinSet`, returning an [`AbortHandle`]
- ```rust
pub fn spawn_on<F>(self: &mut Self, task: F, handle: &Handle) -> AbortHandle
where
F: Future<Output = T> + Send + ''static,
T: Send { /* ... */ }
```
Spawn the provided task on the provided runtime and store it in this
- ```rust
pub fn spawn_local<F>(self: &mut Self, task: F) -> AbortHandle
where
F: Future<Output = T> + ''static { /* ... */ }
```
Spawn the provided task on the current [`LocalSet`] or [`LocalRuntime`]
- ```rust
pub fn spawn_local_on<F>(self: &mut Self, task: F, local_set: &LocalSet) -> AbortHandle
where
F: Future<Output = T> + ''static { /* ... */ }
```
Spawn the provided task on the provided [`LocalSet`] and store it in
- ```rust
pub fn spawn_blocking<F>(self: &mut Self, f: F) -> AbortHandle
where
F: FnOnce() -> T + Send + ''static,
T: Send { /* ... */ }
```
Spawn the blocking code on the blocking threadpool and store
- ```rust
pub fn spawn_blocking_on<F>(self: &mut Self, f: F, handle: &Handle) -> AbortHandle
where
F: FnOnce() -> T + Send + ''static,
T: Send { /* ... */ }
```
Spawn the blocking code on the blocking threadpool of the
- ```rust
pub async fn join_next(self: &mut Self) -> Option<Result<T, JoinError>> { /* ... */ }
```
Waits until one of the tasks in the set completes and returns its output.
- ```rust
pub async fn join_next_with_id(self: &mut Self) -> Option<Result<(Id, T), JoinError>> { /* ... */ }
```
Waits until one of the tasks in the set completes and returns its
- ```rust
pub fn try_join_next(self: &mut Self) -> Option<Result<T, JoinError>> { /* ... */ }
```
Tries to join one of the tasks in the set that has completed and return its output.
- ```rust
pub fn try_join_next_with_id(self: &mut Self) -> Option<Result<(Id, T), JoinError>> { /* ... */ }
```
Tries to join one of the tasks in the set that has completed and return its output,
- ```rust
pub async fn shutdown(self: &mut Self) { /* ... */ }
```
Aborts all tasks and waits for them to finish shutting down.
- ```rust
pub async fn join_all(self: Self) -> Vec<T> { /* ... */ }
```
Awaits the completion of all tasks in this `JoinSet`, returning a vector of their results.
- ```rust
pub fn abort_all(self: &mut Self) { /* ... */ }
```
Aborts all tasks on this `JoinSet`.
- ```rust
pub fn detach_all(self: &mut Self) { /* ... */ }
```
Removes all tasks from this `JoinSet` without aborting them.
- ```rust
pub fn poll_join_next(self: &mut Self, cx: &mut Context<''_>) -> Poll<Option<Result<T, JoinError>>> { /* ... */ }
```
Polls for one of the tasks in the set to complete.
- ```rust
pub fn poll_join_next_with_id(self: &mut Self, cx: &mut Context<''_>) -> Poll<Option<Result<(Id, T), JoinError>>> { /* ... */ }
```
Polls for one of the tasks in the set to complete.
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
```
- **Default**
- ```rust
fn default() -> Self { /* ... */ }
```
- **Drop**
- ```rust
fn drop(self: &mut Self) { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **FromIterator**
- ```rust
fn from_iter<I: IntoIterator<Item = F>>(iter: I) -> Self { /* ... */ }
```
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `Builder`
**Attributes:**
- `Other("#[<cfg>(all(tokio_unstable, feature = \"tracing\"))]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(all(tokio_unstable, feature = \"tracing\"))))]")`
- `Other("#[doc(cfg(all(tokio_unstable, feature = \"tracing\")))]")`
- `MustUse { reason: Some("builders do nothing unless used to spawn a task") }`
A variant of [`task::Builder`] that spawns tasks on a [`JoinSet`] rather
than on the current default runtime.
[`task::Builder`]: crate::task::Builder
```rust
pub struct Builder<''a, T> {
// Some fields omitted
}
```
##### Fields
| Name | Type | Documentation |
|------|------|---------------|
| *private fields* | ... | *Some fields have been omitted* |
##### Implementations
###### Methods
- ```rust
pub fn name(self: Self, name: &''a str) -> Self { /* ... */ }
```
Assigns a name to the task which will be spawned.
- ```rust
pub fn spawn<F>(self: Self, future: F) -> std::io::Result<AbortHandle>
where
F: Future<Output = T> + Send + ''static,
T: Send { /* ... */ }
```
Spawn the provided task with this builder's settings and store it in the
- ```rust
pub fn spawn_on<F>(self: Self, future: F, handle: &Handle) -> std::io::Result<AbortHandle>
where
F: Future<Output = T> + Send + ''static,
T: Send { /* ... */ }
```
Spawn the provided task on the provided [runtime handle] with this
- ```rust
pub fn spawn_blocking<F>(self: Self, f: F) -> std::io::Result<AbortHandle>
where
F: FnOnce() -> T + Send + ''static,
T: Send { /* ... */ }
```
Spawn the blocking code on the blocking threadpool with this builder's
- ```rust
pub fn spawn_blocking_on<F>(self: Self, f: F, handle: &Handle) -> std::io::Result<AbortHandle>
where
F: FnOnce() -> T + Send + ''static,
T: Send { /* ... */ }
```
Spawn the blocking code on the blocking threadpool of the provided
- ```rust
pub fn spawn_local<F>(self: Self, future: F) -> std::io::Result<AbortHandle>
where
F: Future<Output = T> + ''static { /* ... */ }
```
Spawn the provided task on the current [`LocalSet`] with this builder's
- ```rust
pub fn spawn_local_on<F>(self: Self, future: F, local_set: &LocalSet) -> std::io::Result<AbortHandle>
where
F: Future<Output = T> + ''static { /* ... */ }
```
Spawn the provided task on the provided [`LocalSet`] with this builder's
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
## Module `futures`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
Task-related futures.
```rust
pub mod futures { /* ... */ }
```
### Re-exports
#### Re-export `TaskLocalFuture`
```rust
pub use super::task_local::TaskLocalFuture;
```
### Re-exports
#### Re-export `JoinError`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
```rust
pub use crate::runtime::task::JoinError;
```
#### Re-export `JoinHandle`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
```rust
pub use crate::runtime::task::JoinHandle;
```
#### Re-export `spawn_blocking`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
```rust
pub use blocking::spawn_blocking;
```
#### Re-export `spawn`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
```rust
pub use spawn::spawn;
```
#### Re-export `block_in_place`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt-multi-thread\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt-multi-thread\")))]")`
- `Other("#[doc(cfg(feature = \"rt-multi-thread\"))]")`
```rust
pub use blocking::block_in_place;
```
#### Re-export `yield_now`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
```rust
pub use yield_now::yield_now;
```
#### Re-export `spawn_local`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
```rust
pub use local::spawn_local;
```
#### Re-export `LocalSet`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
```rust
pub use local::LocalSet;
```
#### Re-export `LocalEnterGuard`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
```rust
pub use local::LocalEnterGuard;
```
#### Re-export `LocalKey`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
```rust
pub use task_local::LocalKey;
```
#### Re-export `JoinSet`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
- `Other("#[doc(inline)]")`
```rust
pub use join_set::JoinSet;
```
#### Re-export `AbortHandle`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
```rust
pub use crate::runtime::task::AbortHandle;
```
#### Re-export `Id`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
```rust
pub use crate::runtime::task::Id;
```
#### Re-export `id`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
```rust
pub use crate::runtime::task::id;
```
#### Re-export `try_id`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
```rust
pub use crate::runtime::task::try_id;
```
#### Re-export `Builder`
**Attributes:**
- `Other("#[<cfg>(all(tokio_unstable, feature = \"tracing\"))]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(all(tokio_unstable, feature = \"tracing\"))))]")`
- `Other("#[doc(cfg(all(tokio_unstable, feature = \"tracing\")))]")`
```rust
pub use builder::Builder;
```
## Module `time`
**Attributes:**
- `Other("#[<cfg>(feature = \"time\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"time\")))]")`
- `Other("#[doc(cfg(feature = \"time\"))]")`
Utilities for tracking time.
This module provides a number of types for executing code after a set period
of time.
* [`Sleep`] is a future that does no work and completes at a specific [`Instant`]
in time.
* [`Interval`] is a stream yielding a value at a fixed period. It is
initialized with a [`Duration`] and repeatedly yields each time the duration
elapses.
* [`Timeout`]: Wraps a future or stream, setting an upper bound to the amount
of time it is allowed to execute. If the future or stream does not
complete in time, then it is canceled and an error is returned.
These types are sufficient for handling a large number of scenarios
involving time.
These types must be used from within the context of the [`Runtime`](crate::runtime::Runtime).
# Examples
Wait 100ms and print "100 ms have elapsed"
```
use std::time::Duration;
use tokio::time::sleep;
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
sleep(Duration::from_millis(100)).await;
println!("100 ms have elapsed");
# }
```
Require that an operation takes no more than 1s.
```
use tokio::time::{timeout, Duration};
async fn long_future() {
// do work here
}
# async fn dox() {
let res = timeout(Duration::from_secs(1), long_future()).await;
if res.is_err() {
println!("operation timed out");
}
# }
```
A simple example using [`interval`] to execute a task every two seconds.
The difference between [`interval`] and [`sleep`] is that an [`interval`]
measures the time since the last tick, which means that `.tick().await` may
wait for a shorter time than the duration specified for the interval
if some time has passed between calls to `.tick().await`.
If the tick in the example below was replaced with [`sleep`], the task
would only be executed once every three seconds, and not every two
seconds.
```
use tokio::time;
async fn task_that_takes_a_second() {
println!("hello");
time::sleep(time::Duration::from_secs(1)).await
}
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let mut interval = time::interval(time::Duration::from_secs(2));
for _i in 0..5 {
interval.tick().await;
task_that_takes_a_second().await;
}
# }
```
[`interval`]: crate::time::interval()
[`sleep`]: sleep()
```rust
pub mod time { /* ... */ }
```
### Modules
## Module `error`
Time error types.
```rust
pub mod error { /* ... */ }
```
### Types
#### Struct `Error`
Errors encountered by the timer implementation.
Currently, there are two different errors that can occur:
* `shutdown` occurs when a timer operation is attempted, but the timer
instance has been dropped. In this case, the operation will never be able
to complete and the `shutdown` error is returned. This is a permanent
error, i.e., once this error is observed, timer operations will never
succeed in the future.
* `at_capacity` occurs when a timer operation is attempted, but the timer
instance is currently handling its maximum number of outstanding sleep instances.
In this case, the operation is not able to be performed at the current
moment, and `at_capacity` is returned. This is a transient error, i.e., at
some point in the future, if the operation is attempted again, it might
succeed. Callers that observe this error should attempt to [shed load]. One
way to do this would be dropping the future that issued the timer operation.
[shed load]: https://en.wikipedia.org/wiki/Load_Shedding
```rust
pub struct Error(/* private field */);
```
##### Fields
| Index | Type | Documentation |
|-------|------|---------------|
| 0 | `private` | *Private field* |
##### Implementations
###### Methods
- ```rust
pub fn shutdown() -> Error { /* ... */ }
```
Creates an error representing a shutdown timer.
- ```rust
pub fn is_shutdown(self: &Self) -> bool { /* ... */ }
```
Returns `true` if the error was caused by the timer being shutdown.
- ```rust
pub fn at_capacity() -> Error { /* ... */ }
```
Creates an error representing a timer at capacity.
- ```rust
pub fn is_at_capacity(self: &Self) -> bool { /* ... */ }
```
Returns `true` if the error was caused by the timer being at capacity.
- ```rust
pub fn invalid() -> Error { /* ... */ }
```
Creates an error representing a misconfigured timer.
- ```rust
pub fn is_invalid(self: &Self) -> bool { /* ... */ }
```
Returns `true` if the error was caused by the timer being misconfigured.
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Clone**
- ```rust
fn clone(self: &Self) -> Error { /* ... */ }
```
- **CloneToUninit**
- ```rust
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
```
- **Copy**
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Display**
- ```rust
fn fmt(self: &Self, fmt: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
```
- **Error**
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Sync**
- **ToOwned**
- ```rust
fn to_owned(self: &Self) -> T { /* ... */ }
```
- ```rust
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
```
- **ToString**
- ```rust
fn to_string(self: &Self) -> String { /* ... */ }
```
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
#### Struct `Elapsed`
Errors returned by `Timeout`.
This error is returned when a timeout expires before the function was able
to finish.
```rust
pub struct Elapsed(/* private field */);
```
##### Fields
| Index | Type | Documentation |
|-------|------|---------------|
| 0 | `private` | *Private field* |
##### Implementations
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Display**
- ```rust
fn fmt(self: &Self, fmt: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
```
- **Eq**
- **Error**
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- ```rust
fn from(_err: Elapsed) -> std::io::Error { /* ... */ }
```
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **PartialEq**
- ```rust
fn eq(self: &Self, other: &Elapsed) -> bool { /* ... */ }
```
- **RefUnwindSafe**
- **Send**
- **StructuralPartialEq**
- **Sync**
- **ToString**
- ```rust
fn to_string(self: &Self) -> String { /* ... */ }
```
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
### Re-exports
#### Re-export `advance`
**Attributes:**
- `Other("#[<cfg>(feature = \"test-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"test-util\")))]")`
- `Other("#[doc(cfg(feature = \"test-util\"))]")`
```rust
pub use clock::advance;
```
#### Re-export `pause`
**Attributes:**
- `Other("#[<cfg>(feature = \"test-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"test-util\")))]")`
- `Other("#[doc(cfg(feature = \"test-util\"))]")`
```rust
pub use clock::pause;
```
#### Re-export `resume`
**Attributes:**
- `Other("#[<cfg>(feature = \"test-util\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"test-util\")))]")`
- `Other("#[doc(cfg(feature = \"test-util\"))]")`
```rust
pub use clock::resume;
```
#### Re-export `Instant`
```rust
pub use self::instant::Instant;
```
#### Re-export `interval`
```rust
pub use interval::interval;
```
#### Re-export `interval_at`
```rust
pub use interval::interval_at;
```
#### Re-export `Interval`
```rust
pub use interval::Interval;
```
#### Re-export `MissedTickBehavior`
```rust
pub use interval::MissedTickBehavior;
```
#### Re-export `sleep`
```rust
pub use sleep::sleep;
```
#### Re-export `sleep_until`
```rust
pub use sleep::sleep_until;
```
#### Re-export `Sleep`
```rust
pub use sleep::Sleep;
```
#### Re-export `timeout`
**Attributes:**
- `Other("#[doc(inline)]")`
```rust
pub use timeout::timeout;
```
#### Re-export `timeout_at`
**Attributes:**
- `Other("#[doc(inline)]")`
```rust
pub use timeout::timeout_at;
```
#### Re-export `Timeout`
**Attributes:**
- `Other("#[doc(inline)]")`
```rust
pub use timeout::Timeout;
```
#### Re-export `Duration`
**Attributes:**
- `Other("#[doc(no_inline)]")`
```rust
pub use std::time::Duration;
```
## Module `stream`
Due to the `Stream` trait's inclusion in `std` landing later than Tokio's 1.0
release, most of the Tokio stream utilities have been moved into the [`tokio-stream`]
crate.
# Why was `Stream` not included in Tokio 1.0?
Originally, we had planned to ship Tokio 1.0 with a stable `Stream` type
but unfortunately the [RFC] had not been merged in time for `Stream` to
reach `std` on a stable compiler in time for the 1.0 release of Tokio. For
this reason, the team has decided to move all `Stream` based utilities to
the [`tokio-stream`] crate. While this is not ideal, once `Stream` has made
it into the standard library and the `MSRV` period has passed, we will implement
stream for our different types.
While this may seem unfortunate, not all is lost as you can get much of the
`Stream` support with `async/await` and `while let` loops. It is also possible
to create a `impl Stream` from `async fn` using the [`async-stream`] crate.
[`tokio-stream`]: https://docs.rs/tokio-stream
[`async-stream`]: https://docs.rs/async-stream
[RFC]: https://github.com/rust-lang/rfcs/pull/2996
# Example
Convert a [`sync::mpsc::Receiver`] to an `impl Stream`.
```rust,no_run
use tokio::sync::mpsc;
let (tx, mut rx) = mpsc::channel::<usize>(16);
let stream = async_stream::stream! {
while let Some(item) = rx.recv().await {
yield item;
}
};
```
```rust
pub mod stream { /* ... */ }
```
## Module `doc`
**Attributes:**
- `Other("#[<cfg>(all(docsrs, unix))]")`
Types which are documented locally in the Tokio crate, but does not actually
live here.
**Note** this module is only visible on docs.rs, you cannot use it directly
in your own code.
```rust
pub mod doc { /* ... */ }
```
### Modules
## Module `os`
**Attributes:**
- `Other("#[<cfg>(any(feature = \"net\", feature = \"fs\"))]")`
See [`std::os`](https://doc.rust-lang.org/std/os/index.html).
```rust
pub mod os { /* ... */ }
```
### Modules
## Module `windows`
Platform-specific extensions to `std` for Windows.
See [`std::os::windows`](https://doc.rust-lang.org/std/os/windows/index.html).
```rust
pub mod windows { /* ... */ }
```
### Modules
## Module `io`
Windows-specific extensions to general I/O primitives.
See [`std::os::windows::io`](https://doc.rust-lang.org/std/os/windows/io/index.html).
```rust
pub mod io { /* ... */ }
```
### Types
#### Type Alias `RawHandle`
See [`std::os::windows::io::RawHandle`](https://doc.rust-lang.org/std/os/windows/io/type.RawHandle.html)
```rust
pub type RawHandle = crate::doc::NotDefinedHere;
```
#### Type Alias `OwnedHandle`
See [`std::os::windows::io::OwnedHandle`](https://doc.rust-lang.org/std/os/windows/io/struct.OwnedHandle.html)
```rust
pub type OwnedHandle = crate::doc::NotDefinedHere;
```
#### Type Alias `RawSocket`
See [`std::os::windows::io::RawSocket`](https://doc.rust-lang.org/std/os/windows/io/type.RawSocket.html)
```rust
pub type RawSocket = crate::doc::NotDefinedHere;
```
#### Type Alias `BorrowedHandle`
See [`std::os::windows::io::BorrowedHandle`](https://doc.rust-lang.org/std/os/windows/io/struct.BorrowedHandle.html)
```rust
pub type BorrowedHandle<''handle> = crate::doc::NotDefinedHere;
```
#### Type Alias `BorrowedSocket`
See [`std::os::windows::io::BorrowedSocket`](https://doc.rust-lang.org/std/os/windows/io/struct.BorrowedSocket.html)
```rust
pub type BorrowedSocket<''socket> = crate::doc::NotDefinedHere;
```
### Traits
#### Trait `AsRawHandle`
See [`std::os::windows::io::AsRawHandle`](https://doc.rust-lang.org/std/os/windows/io/trait.AsRawHandle.html)
```rust
pub trait AsRawHandle {
/* Associated items */
}
```
##### Required Items
###### Required Methods
- `as_raw_handle`: See [`std::os::windows::io::AsRawHandle::as_raw_handle`](https://doc.rust-lang.org/std/os/windows/io/trait.AsRawHandle.html#tymethod.as_raw_handle)
##### Implementations
This trait is implemented for the following types:
- `File`
- `Stderr`
- `Stdin`
- `Stdout`
- `NamedPipeServer`
- `NamedPipeClient`
- `ChildStdin`
- `ChildStdout`
- `ChildStderr`
#### Trait `FromRawHandle`
See [`std::os::windows::io::FromRawHandle`](https://doc.rust-lang.org/std/os/windows/io/trait.FromRawHandle.html)
```rust
pub trait FromRawHandle {
/* Associated items */
}
```
> This trait is not object-safe and cannot be used in dynamic trait objects.
##### Required Items
###### Required Methods
- `from_raw_handle`: See [`std::os::windows::io::FromRawHandle::from_raw_handle`](https://doc.rust-lang.org/std/os/windows/io/trait.FromRawHandle.html#tymethod.from_raw_handle)
##### Implementations
This trait is implemented for the following types:
- `File`
#### Trait `AsRawSocket`
See [`std::os::windows::io::AsRawSocket`](https://doc.rust-lang.org/std/os/windows/io/trait.AsRawSocket.html)
```rust
pub trait AsRawSocket {
/* Associated items */
}
```
##### Required Items
###### Required Methods
- `as_raw_socket`: See [`std::os::windows::io::AsRawSocket::as_raw_socket`](https://doc.rust-lang.org/std/os/windows/io/trait.AsRawSocket.html#tymethod.as_raw_socket)
##### Implementations
This trait is implemented for the following types:
- `TcpListener`
- `TcpSocket`
- `TcpStream`
- `UdpSocket`
#### Trait `FromRawSocket`
See [`std::os::windows::io::FromRawSocket`](https://doc.rust-lang.org/std/os/windows/io/trait.FromRawSocket.html)
```rust
pub trait FromRawSocket {
/* Associated items */
}
```
> This trait is not object-safe and cannot be used in dynamic trait objects.
##### Required Items
###### Required Methods
- `from_raw_socket`: See [`std::os::windows::io::FromRawSocket::from_raw_socket`](https://doc.rust-lang.org/std/os/windows/io/trait.FromRawSocket.html#tymethod.from_raw_socket)
##### Implementations
This trait is implemented for the following types:
- `TcpSocket`
#### Trait `IntoRawSocket`
See [`std::os::windows::io::IntoRawSocket`](https://doc.rust-lang.org/std/os/windows/io/trait.IntoRawSocket.html)
```rust
pub trait IntoRawSocket {
/* Associated items */
}
```
##### Required Items
###### Required Methods
- `into_raw_socket`: See [`std::os::windows::io::IntoRawSocket::into_raw_socket`](https://doc.rust-lang.org/std/os/windows/io/trait.IntoRawSocket.html#tymethod.into_raw_socket)
##### Implementations
This trait is implemented for the following types:
- `TcpSocket`
#### Trait `AsHandle`
See [`std::os::windows::io::AsHandle`](https://doc.rust-lang.org/std/os/windows/io/trait.AsHandle.html)
```rust
pub trait AsHandle {
/* Associated items */
}
```
##### Required Items
###### Required Methods
- `as_handle`: See [`std::os::windows::io::AsHandle::as_handle`](https://doc.rust-lang.org/std/os/windows/io/trait.AsHandle.html#tymethod.as_handle)
##### Implementations
This trait is implemented for the following types:
- `File`
- `Stderr`
- `Stdin`
- `Stdout`
- `NamedPipeServer`
- `NamedPipeClient`
- `ChildStdin`
- `ChildStdout`
- `ChildStderr`
#### Trait `AsSocket`
See [`std::os::windows::io::AsSocket`](https://doc.rust-lang.org/std/os/windows/io/trait.AsSocket.html)
```rust
pub trait AsSocket {
/* Associated items */
}
```
##### Required Items
###### Required Methods
- `as_socket`: See [`std::os::windows::io::AsSocket::as_socket`](https://doc.rust-lang.org/std/os/windows/io/trait.AsSocket.html#tymethod.as_socket)
##### Implementations
This trait is implemented for the following types:
- `TcpListener`
- `TcpSocket`
- `TcpStream`
- `UdpSocket`
### Types
#### Enum `NotDefinedHere`
The name of a type which is not defined here.
This is typically used as an alias for another type, like so:
```rust,ignore
/// See [some::other::location](https://example.com).
type DEFINED_ELSEWHERE = crate::doc::NotDefinedHere;
```
This type is uninhabitable like the [`never` type] to ensure that no one
will ever accidentally use it.
[`never` type]: https://doc.rust-lang.org/std/primitive.never.html
```rust
pub enum NotDefinedHere {
}
```
##### Variants
##### Implementations
###### Trait Implementations
- **Any**
- ```rust
fn type_id(self: &Self) -> TypeId { /* ... */ }
```
- **Borrow**
- ```rust
fn borrow(self: &Self) -> &T { /* ... */ }
```
- **BorrowMut**
- ```rust
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
```
- **Debug**
- ```rust
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
```
- **Freeze**
- **From**
- ```rust
fn from(t: T) -> T { /* ... */ }
```
Returns the argument unchanged.
- **Instrument**
- **Into**
- ```rust
fn into(self: Self) -> U { /* ... */ }
```
Calls `U::from(self)`.
- **RefUnwindSafe**
- **Send**
- **Source**
- ```rust
fn register(self: &mut Self, _registry: &mio::Registry, _token: mio::Token, _interests: mio::Interest) -> std::io::Result<()> { /* ... */ }
```
- ```rust
fn reregister(self: &mut Self, _registry: &mio::Registry, _token: mio::Token, _interests: mio::Interest) -> std::io::Result<()> { /* ... */ }
```
- ```rust
fn deregister(self: &mut Self, _registry: &mio::Registry) -> std::io::Result<()> { /* ... */ }
```
- **Sync**
- **TryFrom**
- ```rust
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
```
- **TryInto**
- ```rust
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
```
- **Unpin**
- **UnwindSafe**
- **WithSubscriber**
## Macros
### Macro `pin`
**Attributes:**
- `MacroExport`
Pins a value on the stack.
Calls to `async fn` return anonymous [`Future`] values that are `!Unpin`.
These values must be pinned before they can be polled. Calling `.await` will
handle this, but consumes the future. If it is required to call `.await` on
a `&mut _` reference, the caller is responsible for pinning the future.
Pinning may be done by allocating with [`Box::pin`] or by using the stack
with the `pin!` macro.
The following will **fail to compile**:
```compile_fail
async fn my_async_fn() {
// async logic here
}
#[tokio::main]
async fn main() {
let mut future = my_async_fn();
(&mut future).await;
}
```
To make this work requires pinning:
```
use tokio::pin;
async fn my_async_fn() {
// async logic here
}
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let future = my_async_fn();
pin!(future);
(&mut future).await;
# }
```
Pinning is useful when using `select!` and stream operators that require `T:
Stream + Unpin`.
[`Future`]: trait@std::future::Future
[`Box::pin`]: std::boxed::Box::pin
# Usage
The `pin!` macro takes **identifiers** as arguments. It does **not** work
with expressions.
The following does not compile as an expression is passed to `pin!`.
```compile_fail
async fn my_async_fn() {
// async logic here
}
#[tokio::main]
async fn main() {
let mut future = pin!(my_async_fn());
(&mut future).await;
}
```
# Examples
Using with select:
```
use tokio::{pin, select};
use tokio_stream::{self as stream, StreamExt};
async fn my_async_fn() {
// async logic here
}
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let mut stream = stream::iter(vec![1, 2, 3, 4]);
let future = my_async_fn();
pin!(future);
loop {
select! {
_ = &mut future => {
// Stop looping `future` will be polled after completion
break;
}
Some(val) = stream.next() => {
println!("got value = {}", val);
}
}
}
# }
```
Because assigning to a variable followed by pinning is common, there is also
a variant of the macro that supports doing both in one go.
```
use tokio::{pin, select};
async fn my_async_fn() {
// async logic here
}
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
pin! {
let future1 = my_async_fn();
let future2 = my_async_fn();
}
select! {
_ = &mut future1 => {}
_ = &mut future2 => {}
}
# }
```
```rust
pub macro_rules! pin {
/* macro_rules! pin {
($($x:ident),*) => { ... };
($(
let $x:ident = $init:expr;
)*) => { ... };
} */
}
```
### Macro `select`
**Attributes:**
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"macros\")))]")`
- `Other("#[doc(cfg(feature = \"macros\"))]")`
- `MacroExport`
Waits on multiple concurrent branches, returning when the **first** branch
completes, cancelling the remaining branches.
The `select!` macro must be used inside of async functions, closures, and
blocks.
The `select!` macro accepts one or more branches with the following pattern:
```text
<pattern> = <async expression> (, if <precondition>)? => <handler>,
```
Additionally, the `select!` macro may include a single, optional `else`
branch, which evaluates if none of the other branches match their patterns:
```text
else => <expression>
```
The macro aggregates all `<async expression>` expressions and runs them
concurrently on the **current** task. Once the **first** expression
completes with a value that matches its `<pattern>`, the `select!` macro
returns the result of evaluating the completed branch's `<handler>`
expression.
Additionally, each branch may include an optional `if` precondition. If the
precondition returns `false`, then the branch is disabled. The provided
`<async expression>` is still evaluated but the resulting future is never
polled. This capability is useful when using `select!` within a loop.
The complete lifecycle of a `select!` expression is as follows:
1. Evaluate all provided `<precondition>` expressions. If the precondition
returns `false`, disable the branch for the remainder of the current call
to `select!`. Re-entering `select!` due to a loop clears the "disabled"
state.
2. Aggregate the `<async expression>`s from each branch, including the
disabled ones. If the branch is disabled, `<async expression>` is still
evaluated, but the resulting future is not polled.
3. If **all** branches are disabled: go to step 6.
4. Concurrently await on the results for all remaining `<async expression>`s.
5. Once an `<async expression>` returns a value, attempt to apply the value to the
provided `<pattern>`. If the pattern matches, evaluate the `<handler>` and return.
If the pattern **does not** match, disable the current branch for the remainder of
the current call to `select!`. Continue from step 3.
6. Evaluate the `else` expression. If no else expression is provided, panic.
# Runtime characteristics
By running all async expressions on the current task, the expressions are
able to run **concurrently** but not in **parallel**. This means all
expressions are run on the same thread and if one branch blocks the thread,
all other expressions will be unable to continue. If parallelism is
required, spawn each async expression using [`tokio::spawn`] and pass the
join handle to `select!`.
[`tokio::spawn`]: crate::spawn
# Fairness
By default, `select!` randomly picks a branch to check first. This provides
some level of fairness when calling `select!` in a loop with branches that
are always ready.
This behavior can be overridden by adding `biased;` to the beginning of the
macro usage. See the examples for details. This will cause `select` to poll
the futures in the order they appear from top to bottom. There are a few
reasons you may want this:
- The random number generation of `tokio::select!` has a non-zero CPU cost
- Your futures may interact in a way where known polling order is significant
But there is an important caveat to this mode. It becomes your responsibility
to ensure that the polling order of your futures is fair. If for example you
are selecting between a stream and a shutdown future, and the stream has a
huge volume of messages and zero or nearly zero time between them, you should
place the shutdown future earlier in the `select!` list to ensure that it is
always polled, and will not be ignored due to the stream being constantly
ready.
# Panics
The `select!` macro panics if all branches are disabled **and** there is no
provided `else` branch. A branch is disabled when the provided `if`
precondition returns `false` **or** when the pattern does not match the
result of `<async expression>`.
# Cancellation safety
When using `select!` in a loop to receive messages from multiple sources,
you should make sure that the receive call is cancellation safe to avoid
losing messages. This section goes through various common methods and
describes whether they are cancel safe. The lists in this section are not
exhaustive.
The following methods are cancellation safe:
* [`tokio::sync::mpsc::Receiver::recv`](crate::sync::mpsc::Receiver::recv)
* [`tokio::sync::mpsc::UnboundedReceiver::recv`](crate::sync::mpsc::UnboundedReceiver::recv)
* [`tokio::sync::broadcast::Receiver::recv`](crate::sync::broadcast::Receiver::recv)
* [`tokio::sync::watch::Receiver::changed`](crate::sync::watch::Receiver::changed)
* [`tokio::net::TcpListener::accept`](crate::net::TcpListener::accept)
* [`tokio::net::UnixListener::accept`](crate::net::UnixListener::accept)
* [`tokio::signal::unix::Signal::recv`](crate::signal::unix::Signal::recv)
* [`tokio::io::AsyncReadExt::read`](crate::io::AsyncReadExt::read) on any `AsyncRead`
* [`tokio::io::AsyncReadExt::read_buf`](crate::io::AsyncReadExt::read_buf) on any `AsyncRead`
* [`tokio::io::AsyncWriteExt::write`](crate::io::AsyncWriteExt::write) on any `AsyncWrite`
* [`tokio::io::AsyncWriteExt::write_buf`](crate::io::AsyncWriteExt::write_buf) on any `AsyncWrite`
* [`tokio_stream::StreamExt::next`](https://docs.rs/tokio-stream/0.1/tokio_stream/trait.StreamExt.html#method.next) on any `Stream`
* [`futures::stream::StreamExt::next`](https://docs.rs/futures/0.3/futures/stream/trait.StreamExt.html#method.next) on any `Stream`
The following methods are not cancellation safe and can lead to loss of data:
* [`tokio::io::AsyncReadExt::read_exact`](crate::io::AsyncReadExt::read_exact)
* [`tokio::io::AsyncReadExt::read_to_end`](crate::io::AsyncReadExt::read_to_end)
* [`tokio::io::AsyncReadExt::read_to_string`](crate::io::AsyncReadExt::read_to_string)
* [`tokio::io::AsyncWriteExt::write_all`](crate::io::AsyncWriteExt::write_all)
The following methods are not cancellation safe because they use a queue for
fairness and cancellation makes you lose your place in the queue:
* [`tokio::sync::Mutex::lock`](crate::sync::Mutex::lock)
* [`tokio::sync::RwLock::read`](crate::sync::RwLock::read)
* [`tokio::sync::RwLock::write`](crate::sync::RwLock::write)
* [`tokio::sync::Semaphore::acquire`](crate::sync::Semaphore::acquire)
* [`tokio::sync::Notify::notified`](crate::sync::Notify::notified)
To determine whether your own methods are cancellation safe, look for the
location of uses of `.await`. This is because when an asynchronous method is
cancelled, that always happens at an `.await`. If your function behaves
correctly even if it is restarted while waiting at an `.await`, then it is
cancellation safe.
Cancellation safety can be defined in the following way: If you have a
future that has not yet completed, then it must be a no-op to drop that
future and recreate it. This definition is motivated by the situation where
a `select!` is used in a loop. Without this guarantee, you would lose your
progress when another branch completes and you restart the `select!` by
going around the loop.
Be aware that cancelling something that is not cancellation safe is not
necessarily wrong. For example, if you are cancelling a task because the
application is shutting down, then you probably don't care that partially
read data is lost.
# Examples
Basic select with two branches.
```
async fn do_stuff_async() {
// async work
}
async fn more_async_work() {
// more here
}
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
tokio::select! {
_ = do_stuff_async() => {
println!("do_stuff_async() completed first")
}
_ = more_async_work() => {
println!("more_async_work() completed first")
}
};
# }
```
Basic stream selecting.
```
use tokio_stream::{self as stream, StreamExt};
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let mut stream1 = stream::iter(vec![1, 2, 3]);
let mut stream2 = stream::iter(vec![4, 5, 6]);
let next = tokio::select! {
v = stream1.next() => v.unwrap(),
v = stream2.next() => v.unwrap(),
};
assert!(next == 1 || next == 4);
# }
```
Collect the contents of two streams. In this example, we rely on pattern
matching and the fact that `stream::iter` is "fused", i.e. once the stream
is complete, all calls to `next()` return `None`.
```
use tokio_stream::{self as stream, StreamExt};
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let mut stream1 = stream::iter(vec![1, 2, 3]);
let mut stream2 = stream::iter(vec![4, 5, 6]);
let mut values = vec![];
loop {
tokio::select! {
Some(v) = stream1.next() => values.push(v),
Some(v) = stream2.next() => values.push(v),
else => break,
}
}
values.sort();
assert_eq!(&[1, 2, 3, 4, 5, 6], &values[..]);
# }
```
Using the same future in multiple `select!` expressions can be done by passing
a reference to the future. Doing so requires the future to be [`Unpin`]. A
future can be made [`Unpin`] by either using [`Box::pin`] or stack pinning.
[`Unpin`]: std::marker::Unpin
[`Box::pin`]: std::boxed::Box::pin
Here, a stream is consumed for at most 1 second.
```
use tokio_stream::{self as stream, StreamExt};
use tokio::time::{self, Duration};
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let mut stream = stream::iter(vec![1, 2, 3]);
let sleep = time::sleep(Duration::from_secs(1));
tokio::pin!(sleep);
loop {
tokio::select! {
maybe_v = stream.next() => {
if let Some(v) = maybe_v {
println!("got = {}", v);
} else {
break;
}
}
_ = &mut sleep => {
println!("timeout");
break;
}
}
}
# }
```
Joining two values using `select!`.
```
use tokio::sync::oneshot;
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let (tx1, mut rx1) = oneshot::channel();
let (tx2, mut rx2) = oneshot::channel();
tokio::spawn(async move {
tx1.send("first").unwrap();
});
tokio::spawn(async move {
tx2.send("second").unwrap();
});
let mut a = None;
let mut b = None;
while a.is_none() || b.is_none() {
tokio::select! {
v1 = (&mut rx1), if a.is_none() => a = Some(v1.unwrap()),
v2 = (&mut rx2), if b.is_none() => b = Some(v2.unwrap()),
}
}
let res = (a.unwrap(), b.unwrap());
assert_eq!(res.0, "first");
assert_eq!(res.1, "second");
# }
```
Using the `biased;` mode to control polling order.
```
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let mut count = 0u8;
loop {
tokio::select! {
// If you run this example without `biased;`, the polling order is
// pseudo-random, and the assertions on the value of count will
// (probably) fail.
biased;
_ = async {}, if count < 1 => {
count += 1;
assert_eq!(count, 1);
}
_ = async {}, if count < 2 => {
count += 1;
assert_eq!(count, 2);
}
_ = async {}, if count < 3 => {
count += 1;
assert_eq!(count, 3);
}
_ = async {}, if count < 4 => {
count += 1;
assert_eq!(count, 4);
}
else => {
break;
}
};
}
# }
```
## Avoid racy `if` preconditions
Given that `if` preconditions are used to disable `select!` branches, some
caution must be used to avoid missing values.
For example, here is **incorrect** usage of `sleep` with `if`. The objective
is to repeatedly run an asynchronous task for up to 50 milliseconds.
However, there is a potential for the `sleep` completion to be missed.
```no_run,should_panic
use tokio::time::{self, Duration};
async fn some_async_work() {
// do work
}
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let sleep = time::sleep(Duration::from_millis(50));
tokio::pin!(sleep);
while !sleep.is_elapsed() {
tokio::select! {
_ = &mut sleep, if !sleep.is_elapsed() => {
println!("operation timed out");
}
_ = some_async_work() => {
println!("operation completed");
}
}
}
panic!("This example shows how not to do it!");
# }
```
In the above example, `sleep.is_elapsed()` may return `true` even if
`sleep.poll()` never returned `Ready`. This opens up a potential race
condition where `sleep` expires between the `while !sleep.is_elapsed()`
check and the call to `select!` resulting in the `some_async_work()` call to
run uninterrupted despite the sleep having elapsed.
One way to write the above example without the race would be:
```
use tokio::time::{self, Duration};
async fn some_async_work() {
# time::sleep(Duration::from_millis(10)).await;
// do work
}
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let sleep = time::sleep(Duration::from_millis(50));
tokio::pin!(sleep);
loop {
tokio::select! {
_ = &mut sleep => {
println!("operation timed out");
break;
}
_ = some_async_work() => {
println!("operation completed");
}
}
}
# }
```
# Alternatives from the Ecosystem
The `select!` macro is a powerful tool for managing multiple asynchronous
branches, enabling tasks to run concurrently within the same thread. However,
its use can introduce challenges, particularly around cancellation safety, which
can lead to subtle and hard-to-debug errors. For many use cases, ecosystem
alternatives may be preferable as they mitigate these concerns by offering
clearer syntax, more predictable control flow, and reducing the need to manually
handle issues like fuse semantics or cancellation safety.
## Merging Streams
For cases where `loop { select! { ... } }` is used to poll multiple tasks,
stream merging offers a concise alternative, inherently handle cancellation-safe
processing, removing the risk of data loss. Libraries such as [`tokio_stream`],
[`futures::stream`] and [`futures_concurrency`] provide tools for merging
streams and handling their outputs sequentially.
[`tokio_stream`]: https://docs.rs/tokio-stream/latest/tokio_stream/
[`futures::stream`]: https://docs.rs/futures/latest/futures/stream/
[`futures_concurrency`]: https://docs.rs/futures-concurrency/latest/futures_concurrency/
### Example with `select!`
```
struct File;
struct Channel;
struct Socket;
impl Socket {
async fn read_packet(&mut self) -> Vec<u8> {
vec![]
}
}
async fn read_send(_file: &mut File, _channel: &mut Channel) {
// do work that is not cancel safe
}
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
// open our IO types
let mut file = File;
let mut channel = Channel;
let mut socket = Socket;
loop {
tokio::select! {
_ = read_send(&mut file, &mut channel) => { /* ... */ },
_data = socket.read_packet() => { /* ... */ }
_ = futures::future::ready(()) => break
}
}
# }
```
### Moving to `merge`
By using merge, you can unify multiple asynchronous tasks into a single stream,
eliminating the need to manage tasks manually and reducing the risk of
unintended behavior like data loss.
```
use std::pin::pin;
use futures::stream::unfold;
use tokio_stream::StreamExt;
struct File;
struct Channel;
struct Socket;
impl Socket {
async fn read_packet(&mut self) -> Vec<u8> {
vec![]
}
}
async fn read_send(_file: &mut File, _channel: &mut Channel) {
// do work that is not cancel safe
}
enum Message {
Stop,
Sent,
Data(Vec<u8>),
}
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
// open our IO types
let file = File;
let channel = Channel;
let socket = Socket;
let a = unfold((file, channel), |(mut file, mut channel)| async {
read_send(&mut file, &mut channel).await;
Some((Message::Sent, (file, channel)))
});
let b = unfold(socket, |mut socket| async {
let data = socket.read_packet().await;
Some((Message::Data(data), socket))
});
let c = tokio_stream::iter([Message::Stop]);
let mut s = pin!(a.merge(b).merge(c));
while let Some(msg) = s.next().await {
match msg {
Message::Data(_data) => { /* ... */ }
Message::Sent => continue,
Message::Stop => break,
}
}
# }
```
## Racing Futures
If you need to wait for the first completion among several asynchronous tasks,
ecosystem utilities such as
[`futures`](https://docs.rs/futures/latest/futures/),
[`futures-lite`](https://docs.rs/futures-lite/latest/futures_lite/) or
[`futures-concurrency`](https://docs.rs/futures-concurrency/latest/futures_concurrency/)
provide streamlined syntax for racing futures:
- [`futures_concurrency::future::Race`](https://docs.rs/futures-concurrency/latest/futures_concurrency/future/trait.Race.html)
- [`futures::select`](https://docs.rs/futures/latest/futures/macro.select.html)
- [`futures::stream::select_all`](https://docs.rs/futures/latest/futures/stream/select_all/index.html) (for streams)
- [`futures_lite::future::or`](https://docs.rs/futures-lite/latest/futures_lite/future/fn.or.html)
- [`futures_lite::future::race`](https://docs.rs/futures-lite/latest/futures_lite/future/fn.race.html)
```
use futures_concurrency::future::Race;
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let task_a = async { Ok("ok") };
let task_b = async { Err("error") };
let result = (task_a, task_b).race().await;
match result {
Ok(output) => println!("First task completed with: {output}"),
Err(err) => eprintln!("Error occurred: {err}"),
}
# }
```
```rust
pub macro_rules! select {
/* macro_rules! select {
{
$(
biased;
)?
$(
$bind:pat = $fut:expr $(, if $cond:expr)? => $handler:expr,
)*
$(
else => $els:expr $(,)?
)?
} => { ... };
} */
}
```
### Macro `join`
**Attributes:**
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"macros\")))]")`
- `Other("#[doc(cfg(feature = \"macros\"))]")`
- `MacroExport`
Waits on multiple concurrent branches, returning when **all** branches
complete.
The `join!` macro must be used inside of async functions, closures, and
blocks.
The `join!` macro takes a list of async expressions and evaluates them
concurrently on the same task. Each async expression evaluates to a future
and the futures from each expression are multiplexed on the current task.
When working with async expressions returning `Result`, `join!` will wait
for **all** branches complete regardless if any complete with `Err`. Use
[`try_join!`] to return early when `Err` is encountered.
[`try_join!`]: crate::try_join
# Notes
The supplied futures are stored inline and do not require allocating a
`Vec`.
## Runtime characteristics
By running all async expressions on the current task, the expressions are
able to run **concurrently** but not in **parallel**. This means all
expressions are run on the same thread and if one branch blocks the thread,
all other expressions will be unable to continue. If parallelism is
required, spawn each async expression using [`tokio::spawn`] and pass the
join handle to `join!`.
[`tokio::spawn`]: crate::spawn
## Fairness
By default, `join!`'s generated future rotates which contained
future is polled first whenever it is woken.
This behavior can be overridden by adding `biased;` to the beginning of the
macro usage. See the examples for details. This will cause `join` to poll
the futures in the order they appear from top to bottom.
You may want this if your futures may interact in a way where known polling order is significant.
But there is an important caveat to this mode. It becomes your responsibility
to ensure that the polling order of your futures is fair. If for example you
are joining a stream and a shutdown future, and the stream has a
huge volume of messages that takes a long time to finish processing per poll, you should
place the shutdown future earlier in the `join!` list to ensure that it is
always polled, and will not be delayed due to the stream future taking a long time to return
`Poll::Pending`.
# Examples
Basic join with two branches
```
async fn do_stuff_async() {
// async work
}
async fn more_async_work() {
// more here
}
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let (first, second) = tokio::join!(
do_stuff_async(),
more_async_work());
// do something with the values
# }
```
Using the `biased;` mode to control polling order.
```
# #[cfg(not(target_family = "wasm"))]
# {
async fn do_stuff_async() {
// async work
}
async fn more_async_work() {
// more here
}
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let (first, second) = tokio::join!(
biased;
do_stuff_async(),
more_async_work()
);
// do something with the values
# }
# }
```
```rust
pub macro_rules! join {
/* macro_rules! join {
($(biased;)? $($future:expr),*) => { ... };
} */
}
```
### Macro `try_join`
**Attributes:**
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"macros\")))]")`
- `Other("#[doc(cfg(feature = \"macros\"))]")`
- `MacroExport`
Waits on multiple concurrent branches, returning when **all** branches
complete with `Ok(_)` or on the first `Err(_)`.
The `try_join!` macro must be used inside of async functions, closures, and
blocks.
Similar to [`join!`], the `try_join!` macro takes a list of async
expressions and evaluates them concurrently on the same task. Each async
expression evaluates to a future and the futures from each expression are
multiplexed on the current task. The `try_join!` macro returns when **all**
branches return with `Ok` or when the **first** branch returns with `Err`.
[`join!`]: macro@join
# Notes
The supplied futures are stored inline and do not require allocating a
`Vec`.
## Runtime characteristics
By running all async expressions on the current task, the expressions are
able to run **concurrently** but not in **parallel**. This means all
expressions are run on the same thread and if one branch blocks the thread,
all other expressions will be unable to continue. If parallelism is
required, spawn each async expression using [`tokio::spawn`] and pass the
join handle to `try_join!`.
[`tokio::spawn`]: crate::spawn
## Fairness
By default, `try_join!`'s generated future rotates which
contained future is polled first whenever it is woken.
This behavior can be overridden by adding `biased;` to the beginning of the
macro usage. See the examples for details. This will cause `try_join` to poll
the futures in the order they appear from top to bottom.
You may want this if your futures may interact in a way where known polling order is significant.
But there is an important caveat to this mode. It becomes your responsibility
to ensure that the polling order of your futures is fair. If for example you
are joining a stream and a shutdown future, and the stream has a
huge volume of messages that takes a long time to finish processing per poll, you should
place the shutdown future earlier in the `try_join!` list to ensure that it is
always polled, and will not be delayed due to the stream future taking a long time to return
`Poll::Pending`.
# Examples
Basic `try_join` with two branches.
```
async fn do_stuff_async() -> Result<(), &'static str> {
// async work
# Ok(())
}
async fn more_async_work() -> Result<(), &'static str> {
// more here
# Ok(())
}
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let res = tokio::try_join!(
do_stuff_async(),
more_async_work());
match res {
Ok((first, second)) => {
// do something with the values
}
Err(err) => {
println!("processing failed; error = {}", err);
}
}
# }
```
Using `try_join!` with spawned tasks.
```
use tokio::task::JoinHandle;
async fn do_stuff_async() -> Result<(), &'static str> {
// async work
# Err("failed")
}
async fn more_async_work() -> Result<(), &'static str> {
// more here
# Ok(())
}
async fn flatten<T>(handle: JoinHandle<Result<T, &'static str>>) -> Result<T, &'static str> {
match handle.await {
Ok(Ok(result)) => Ok(result),
Ok(Err(err)) => Err(err),
Err(err) => Err("handling failed"),
}
}
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let handle1 = tokio::spawn(do_stuff_async());
let handle2 = tokio::spawn(more_async_work());
match tokio::try_join!(flatten(handle1), flatten(handle2)) {
Ok(val) => {
// do something with the values
}
Err(err) => {
println!("Failed with {}.", err);
# assert_eq!(err, "failed");
}
}
# }
```
Using the `biased;` mode to control polling order.
```
async fn do_stuff_async() -> Result<(), &'static str> {
// async work
# Ok(())
}
async fn more_async_work() -> Result<(), &'static str> {
// more here
# Ok(())
}
# #[tokio::main(flavor = "current_thread")]
# async fn main() {
let res = tokio::try_join!(
biased;
do_stuff_async(),
more_async_work()
);
match res {
Ok((first, second)) => {
// do something with the values
}
Err(err) => {
println!("processing failed; error = {}", err);
}
}
# }
```
```rust
pub macro_rules! try_join {
/* macro_rules! try_join {
($(biased;)? $($future:expr),*) => { ... };
} */
}
```
### Macro `task_local`
**Attributes:**
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
- `MacroExport`
Declares a new task-local key of type [`tokio::task::LocalKey`].
# Syntax
The macro wraps any number of static declarations and makes them local to the current task.
Publicity and attributes for each static is preserved. For example:
# Examples
```
# use tokio::task_local;
task_local! {
pub static ONE: u32;
#[allow(unused)]
static TWO: f32;
}
# fn main() {}
```
See [`LocalKey` documentation][`tokio::task::LocalKey`] for more
information.
[`tokio::task::LocalKey`]: struct@crate::task::LocalKey
```rust
pub macro_rules! task_local {
/* macro_rules! task_local {
() => { ... };
($(#[$attr:meta])* $vis:vis static $name:ident: $t:ty; $($rest:tt)*) => { ... };
($(#[$attr:meta])* $vis:vis static $name:ident: $t:ty) => { ... };
} */
}
```
## Re-exports
### Re-export `spawn`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
```rust
pub use task::spawn;
```
### Re-export `main`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
- `Other("#[<cfg>(feature = \"rt-multi-thread\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"macros\")))]")`
- `Other("#[doc(cfg(feature = \"macros\"))]")`
- `Other("#[doc(inline)]")`
```rust
pub use tokio_macros::main;
```
### Re-export `test`
**Attributes:**
- `Other("#[<cfg>(feature = \"rt\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"rt\")))]")`
- `Other("#[doc(cfg(feature = \"rt\"))]")`
- `Other("#[<cfg>(feature = \"rt-multi-thread\")]")`
- `Other("#[<cfg_attr>(docsrs, doc(cfg(feature = \"macros\")))]")`
- `Other("#[doc(cfg(feature = \"macros\"))]")`
- `Other("#[doc(inline)]")`
```rust
pub use tokio_macros::test;
```