1#![allow(
2 clippy::cognitive_complexity,
3 clippy::large_enum_variant,
4 clippy::module_inception,
5 clippy::needless_doctest_main
6)]
7#![warn(
8 missing_debug_implementations,
9 missing_docs,
10 rust_2018_idioms,
11 unreachable_pub
12)]
13#![deny(unused_must_use)]
14#![doc(test(
15 no_crate_inject,
16 attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables))
17))]
18#![cfg_attr(docsrs, feature(doc_cfg))]
19#![cfg_attr(docsrs, allow(unused_attributes))]
20#![cfg_attr(loom, allow(dead_code, unreachable_pub))]
21
22//! A runtime for writing reliable network applications without compromising speed.
23//!
24//! Tokio is an event-driven, non-blocking I/O platform for writing asynchronous
25//! applications with the Rust programming language. At a high level, it
26//! provides a few major components:
27//!
28//! * Tools for [working with asynchronous tasks][tasks], including
29//! [synchronization primitives and channels][sync] and [timeouts, sleeps, and
30//! intervals][time].
31//! * APIs for [performing asynchronous I/O][io], including [TCP and UDP][net] sockets,
32//! [filesystem][fs] operations, and [process] and [signal] management.
33//! * A [runtime] for executing asynchronous code, including a task scheduler,
34//! an I/O driver backed by the operating system's event queue (`epoll`, `kqueue`,
35//! `IOCP`, etc...), and a high performance timer.
36//!
37//! Guide level documentation is found on the [website].
38//!
39//! [tasks]: #working-with-tasks
40//! [sync]: crate::sync
41//! [time]: crate::time
42//! [io]: #asynchronous-io
43//! [net]: crate::net
44//! [fs]: crate::fs
45//! [process]: crate::process
46//! [signal]: crate::signal
47//! [fs]: crate::fs
48//! [runtime]: crate::runtime
49//! [website]: https://tokio.rs/tokio/tutorial
50//!
51//! # A Tour of Tokio
52//!
53//! Tokio consists of a number of modules that provide a range of functionality
54//! essential for implementing asynchronous applications in Rust. In this
55//! section, we will take a brief tour of Tokio, summarizing the major APIs and
56//! their uses.
57//!
58//! The easiest way to get started is to enable all features. Do this by
59//! enabling the `full` feature flag:
60//!
61//! ```toml
62//! tokio = { version = "1", features = ["full"] }
63//! ```
64//!
65//! ### Authoring applications
66//!
67//! Tokio is great for writing applications and most users in this case shouldn't
68//! worry too much about what features they should pick. If you're unsure, we suggest
69//! going with `full` to ensure that you don't run into any road blocks while you're
70//! building your application.
71//!
72//! #### Example
73//!
74//! This example shows the quickest way to get started with Tokio.
75//!
76//! ```toml
77//! tokio = { version = "1", features = ["full"] }
78//! ```
79//!
80//! ### Authoring libraries
81//!
82//! As a library author your goal should be to provide the lightest weight crate
83//! that is based on Tokio. To achieve this you should ensure that you only enable
84//! the features you need. This allows users to pick up your crate without having
85//! to enable unnecessary features.
86//!
87//! #### Example
88//!
89//! This example shows how you may want to import features for a library that just
90//! needs to `tokio::spawn` and use a `TcpStream`.
91//!
92//! ```toml
93//! tokio = { version = "1", features = ["rt", "net"] }
94//! ```
95//!
96//! ## Working With Tasks
97//!
98//! Asynchronous programs in Rust are based around lightweight, non-blocking
99//! units of execution called [_tasks_][tasks]. The [`tokio::task`] module provides
100//! important tools for working with tasks:
101//!
102//! * The [`spawn`] function and [`JoinHandle`] type, for scheduling a new task
103//! on the Tokio runtime and awaiting the output of a spawned task, respectively,
104//! * Functions for [running blocking operations][blocking] in an asynchronous
105//! task context.
106//!
107//! The [`tokio::task`] module is present only when the "rt" feature flag
108//! is enabled.
109//!
110//! [tasks]: task/index.html#what-are-tasks
111//! [`tokio::task`]: crate::task
112//! [`spawn`]: crate::task::spawn()
113//! [`JoinHandle`]: crate::task::JoinHandle
114//! [blocking]: task/index.html#blocking-and-yielding
115//!
116//! The [`tokio::sync`] module contains synchronization primitives to use when
117//! needing to communicate or share data. These include:
118//!
119//! * channels ([`oneshot`], [`mpsc`], [`watch`], and [`broadcast`]), for sending values
120//! between tasks,
121//! * a non-blocking [`Mutex`], for controlling access to a shared, mutable
122//! value,
123//! * an asynchronous [`Barrier`] type, for multiple tasks to synchronize before
124//! beginning a computation.
125//!
126//! The `tokio::sync` module is present only when the "sync" feature flag is
127//! enabled.
128//!
129//! [`tokio::sync`]: crate::sync
130//! [`Mutex`]: crate::sync::Mutex
131//! [`Barrier`]: crate::sync::Barrier
132//! [`oneshot`]: crate::sync::oneshot
133//! [`mpsc`]: crate::sync::mpsc
134//! [`watch`]: crate::sync::watch
135//! [`broadcast`]: crate::sync::broadcast
136//!
137//! The [`tokio::time`] module provides utilities for tracking time and
138//! scheduling work. This includes functions for setting [timeouts][timeout] for
139//! tasks, [sleeping][sleep] work to run in the future, or [repeating an operation at an
140//! interval][interval].
141//!
142//! In order to use `tokio::time`, the "time" feature flag must be enabled.
143//!
144//! [`tokio::time`]: crate::time
145//! [sleep]: crate::time::sleep()
146//! [interval]: crate::time::interval()
147//! [timeout]: crate::time::timeout()
148//!
149//! Finally, Tokio provides a _runtime_ for executing asynchronous tasks. Most
150//! applications can use the [`#[tokio::main]`][main] macro to run their code on the
151//! Tokio runtime. However, this macro provides only basic configuration options. As
152//! an alternative, the [`tokio::runtime`] module provides more powerful APIs for configuring
153//! and managing runtimes. You should use that module if the `#[tokio::main]` macro doesn't
154//! provide the functionality you need.
155//!
156//! Using the runtime requires the "rt" or "rt-multi-thread" feature flags, to
157//! enable the current-thread [single-threaded scheduler][rt] and the [multi-thread
158//! scheduler][rt-multi-thread], respectively. See the [`runtime` module
159//! documentation][rt-features] for details. In addition, the "macros" feature
160//! flag enables the `#[tokio::main]` and `#[tokio::test]` attributes.
161//!
162//! [main]: attr.main.html
163//! [`tokio::runtime`]: crate::runtime
164//! [`Builder`]: crate::runtime::Builder
165//! [`Runtime`]: crate::runtime::Runtime
166//! [rt]: runtime/index.html#current-thread-scheduler
167//! [rt-multi-thread]: runtime/index.html#multi-thread-scheduler
168//! [rt-features]: runtime/index.html#runtime-scheduler
169//!
170//! ## CPU-bound tasks and blocking code
171//!
172//! Tokio is able to concurrently run many tasks on a few threads by repeatedly
173//! swapping the currently running task on each thread. However, this kind of
174//! swapping can only happen at `.await` points, so code that spends a long time
175//! without reaching an `.await` will prevent other tasks from running. To
176//! combat this, Tokio provides two kinds of threads: Core threads and blocking threads.
177//!
178//! The core threads are where all asynchronous code runs, and Tokio will by default
179//! spawn one for each CPU core. You can use the environment variable `TOKIO_WORKER_THREADS`
180//! to override the default value.
181//!
182//! The blocking threads are spawned on demand, can be used to run blocking code
183//! that would otherwise block other tasks from running and are kept alive when
184//! not used for a certain amount of time which can be configured with [`thread_keep_alive`].
185//! Since it is not possible for Tokio to swap out blocking tasks, like it
186//! can do with asynchronous code, the upper limit on the number of blocking
187//! threads is very large. These limits can be configured on the [`Builder`].
188//!
189//! To spawn a blocking task, you should use the [`spawn_blocking`] function.
190//!
191//! [`Builder`]: crate::runtime::Builder
192//! [`spawn_blocking`]: crate::task::spawn_blocking()
193//! [`thread_keep_alive`]: crate::runtime::Builder::thread_keep_alive()
194//!
195//! ```
196//! #[tokio::main]
197//! async fn main() {
198//! // This is running on a core thread.
199//!
200//! let blocking_task = tokio::task::spawn_blocking(|| {
201//! // This is running on a blocking thread.
202//! // Blocking here is ok.
203//! });
204//!
205//! // We can wait for the blocking task like this:
206//! // If the blocking task panics, the unwrap below will propagate the
207//! // panic.
208//! blocking_task.await.unwrap();
209//! }
210//! ```
211//!
212//! If your code is CPU-bound and you wish to limit the number of threads used
213//! to run it, you should use a separate thread pool dedicated to CPU bound tasks.
214//! For example, you could consider using the [rayon] library for CPU-bound
215//! tasks. It is also possible to create an extra Tokio runtime dedicated to
216//! CPU-bound tasks, but if you do this, you should be careful that the extra
217//! runtime runs _only_ CPU-bound tasks, as IO-bound tasks on that runtime
218//! will behave poorly.
219//!
220//! Hint: If using rayon, you can use a [`oneshot`] channel to send the result back
221//! to Tokio when the rayon task finishes.
222//!
223//! [rayon]: https://docs.rs/rayon
224//! [`oneshot`]: crate::sync::oneshot
225//!
226//! ## Asynchronous IO
227//!
228//! As well as scheduling and running tasks, Tokio provides everything you need
229//! to perform input and output asynchronously.
230//!
231//! The [`tokio::io`] module provides Tokio's asynchronous core I/O primitives,
232//! the [`AsyncRead`], [`AsyncWrite`], and [`AsyncBufRead`] traits. In addition,
233//! when the "io-util" feature flag is enabled, it also provides combinators and
234//! functions for working with these traits, forming as an asynchronous
235//! counterpart to [`std::io`].
236//!
237//! Tokio also includes APIs for performing various kinds of I/O and interacting
238//! with the operating system asynchronously. These include:
239//!
240//! * [`tokio::net`], which contains non-blocking versions of [TCP], [UDP], and
241//! [Unix Domain Sockets][UDS] (enabled by the "net" feature flag),
242//! * [`tokio::fs`], similar to [`std::fs`] but for performing filesystem I/O
243//! asynchronously (enabled by the "fs" feature flag),
244//! * [`tokio::signal`], for asynchronously handling Unix and Windows OS signals
245//! (enabled by the "signal" feature flag),
246//! * [`tokio::process`], for spawning and managing child processes (enabled by
247//! the "process" feature flag).
248//!
249//! [`tokio::io`]: crate::io
250//! [`AsyncRead`]: crate::io::AsyncRead
251//! [`AsyncWrite`]: crate::io::AsyncWrite
252//! [`AsyncBufRead`]: crate::io::AsyncBufRead
253//! [`std::io`]: std::io
254//! [`tokio::net`]: crate::net
255//! [TCP]: crate::net::tcp
256//! [UDP]: crate::net::UdpSocket
257//! [UDS]: crate::net::unix
258//! [`tokio::fs`]: crate::fs
259//! [`std::fs`]: std::fs
260//! [`tokio::signal`]: crate::signal
261//! [`tokio::process`]: crate::process
262//!
263//! # Examples
264//!
265//! A simple TCP echo server:
266//!
267//! ```no_run
268//! use tokio::net::TcpListener;
269//! use tokio::io::{AsyncReadExt, AsyncWriteExt};
270//!
271//! #[tokio::main]
272//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
273//! let listener = TcpListener::bind("127.0.0.1:8080").await?;
274//!
275//! loop {
276//! let (mut socket, _) = listener.accept().await?;
277//!
278//! tokio::spawn(async move {
279//! let mut buf = [0; 1024];
280//!
281//! // In a loop, read data from the socket and write the data back.
282//! loop {
283//! let n = match socket.read(&mut buf).await {
284//! // socket closed
285//! Ok(n) if n == 0 => return,
286//! Ok(n) => n,
287//! Err(e) => {
288//! eprintln!("failed to read from socket; err = {:?}", e);
289//! return;
290//! }
291//! };
292//!
293//! // Write the data back
294//! if let Err(e) = socket.write_all(&buf[0..n]).await {
295//! eprintln!("failed to write to socket; err = {:?}", e);
296//! return;
297//! }
298//! }
299//! });
300//! }
301//! }
302//! ```
303//!
304//! ## Feature flags
305//!
306//! Tokio uses a set of [feature flags] to reduce the amount of compiled code. It
307//! is possible to just enable certain features over others. By default, Tokio
308//! does not enable any features but allows one to enable a subset for their use
309//! case. Below is a list of the available feature flags. You may also notice
310//! above each function, struct and trait there is listed one or more feature flags
311//! that are required for that item to be used. If you are new to Tokio it is
312//! recommended that you use the `full` feature flag which will enable all public APIs.
313//! Beware though that this will pull in many extra dependencies that you may not
314//! need.
315//!
316//! - `full`: Enables all features listed below except `test-util` and `tracing`.
317//! - `rt`: Enables `tokio::spawn`, the current-thread scheduler,
318//! and non-scheduler utilities.
319//! - `rt-multi-thread`: Enables the heavier, multi-threaded, work-stealing scheduler.
320//! - `io-util`: Enables the IO based `Ext` traits.
321//! - `io-std`: Enable `Stdout`, `Stdin` and `Stderr` types.
322//! - `net`: Enables `tokio::net` types such as `TcpStream`, `UnixStream` and
323//! `UdpSocket`, as well as (on Unix-like systems) `AsyncFd` and (on
324//! FreeBSD) `PollAio`.
325//! - `time`: Enables `tokio::time` types and allows the schedulers to enable
326//! the built in timer.
327//! - `process`: Enables `tokio::process` types.
328//! - `macros`: Enables `#[tokio::main]` and `#[tokio::test]` macros.
329//! - `sync`: Enables all `tokio::sync` types.
330//! - `signal`: Enables all `tokio::signal` types.
331//! - `fs`: Enables `tokio::fs` types.
332//! - `test-util`: Enables testing based infrastructure for the Tokio runtime.
333//! - `parking_lot`: As a potential optimization, use the `_parking_lot_` crate's
334//! synchronization primitives internally. Also, this
335//! dependency is necessary to construct some of our primitives
336//! in a `const` context. `MSRV` may increase according to the
337//! `_parking_lot_` release in use.
338//!
339//! _Note: `AsyncRead` and `AsyncWrite` traits do not require any features and are
340//! always available._
341//!
342//! ### Unstable features
343//!
344//! Some feature flags are only available when specifying the `tokio_unstable` flag:
345//!
346//! - `tracing`: Enables tracing events.
347//!
348//! Likewise, some parts of the API are only available with the same flag:
349//!
350//! - [`task::Builder`]
351//! - Some methods on [`task::JoinSet`]
352//! - [`runtime::RuntimeMetrics`]
353//! - [`runtime::Builder::unhandled_panic`]
354//! - [`task::Id`]
355//!
356//! This flag enables **unstable** features. The public API of these features
357//! may break in 1.x releases. To enable these features, the `--cfg
358//! tokio_unstable` argument must be passed to `rustc` when compiling. This
359//! serves to explicitly opt-in to features which may break semver conventions,
360//! since Cargo [does not yet directly support such opt-ins][unstable features].
361//!
362//! You can specify it in your project's `.cargo/config.toml` file:
363//!
364//! ```toml
365//! [build]
366//! rustflags = ["--cfg", "tokio_unstable"]
367//! ```
368//!
369//! Alternatively, you can specify it with an environment variable:
370//!
371//! ```sh
372//! ## Many *nix shells:
373//! export RUSTFLAGS="--cfg tokio_unstable"
374//! cargo build
375//! ```
376//!
377//! ```powershell
378//! ## Windows PowerShell:
379//! $Env:RUSTFLAGS="--cfg tokio_unstable"
380//! cargo build
381//! ```
382//!
383//! [unstable features]: https://internals.rust-lang.org/t/feature-request-unstable-opt-in-non-transitive-crate-features/16193#why-not-a-crate-feature-2
384//! [feature flags]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section
385//!
386//! ## Supported platforms
387//!
388//! Tokio currently guarantees support for the following platforms:
389//!
390//! * Linux
391//! * Windows
392//! * Android (API level 21)
393//! * macOS
394//! * iOS
395//! * FreeBSD
396//!
397//! Tokio will continue to support these platforms in the future. However,
398//! future releases may change requirements such as the minimum required libc
399//! version on Linux, the API level on Android, or the supported FreeBSD
400//! release.
401//!
402//! Beyond the above platforms, Tokio is intended to work on all platforms
403//! supported by the mio crate. You can find a longer list [in mio's
404//! documentation][mio-supported]. However, these additional platforms may
405//! become unsupported in the future.
406//!
407//! Note that Wine is considered to be a different platform from Windows. See
408//! mio's documentation for more information on Wine support.
409//!
410//! [mio-supported]: https://crates.io/crates/mio#platforms
411//!
412//! ### `WASM` support
413//!
414//! Tokio has some limited support for the `WASM` platform. Without the
415//! `tokio_unstable` flag, the following features are supported:
416//!
417//! * `sync`
418//! * `macros`
419//! * `io-util`
420//! * `rt`
421//! * `time`
422//!
423//! Enabling any other feature (including `full`) will cause a compilation
424//! failure.
425//!
426//! The `time` module will only work on `WASM` platforms that have support for
427//! timers (e.g. wasm32-wasi). The timing functions will panic if used on a `WASM`
428//! platform that does not support timers.
429//!
430//! Note also that if the runtime becomes indefinitely idle, it will panic
431//! immediately instead of blocking forever. On platforms that don't support
432//! time, this means that the runtime can never be idle in any way.
433//!
434//! ### Unstable `WASM` support
435//!
436//! Tokio also has unstable support for some additional `WASM` features. This
437//! requires the use of the `tokio_unstable` flag.
438//!
439//! Using this flag enables the use of `tokio::net` on the wasm32-wasi target.
440//! However, not all methods are available on the networking types as `WASI`
441//! currently does not support the creation of new sockets from within `WASM`.
442//! Because of this, sockets must currently be created via the `FromRawFd`
443//! trait.
444
445// Test that pointer width is compatible. This asserts that e.g. usize is at
446// least 32 bits, which a lot of components in Tokio currently assumes.
447//
448// TODO: improve once we have MSRV access to const eval to make more flexible.
449#[cfg(not(any(
450 target_pointer_width = "32",
451 target_pointer_width = "64",
452 target_pointer_width = "128"
453)))]
454compile_error! {
455 "Tokio requires the platform pointer width to be 32, 64, or 128 bits"
456}
457
458#[cfg(all(
459 not(tokio_unstable),
460 target_family = "wasm",
461 any(
462 feature = "fs",
463 feature = "io-std",
464 feature = "net",
465 feature = "process",
466 feature = "rt-multi-thread",
467 feature = "signal"
468 )
469))]
470compile_error!("Only features sync,macros,io-util,rt,time are supported on wasm.");
471
472#[cfg(all(not(tokio_unstable), tokio_taskdump))]
473compile_error!("The `tokio_taskdump` feature requires `--cfg tokio_unstable`.");
474
475#[cfg(all(
476 tokio_taskdump,
477 not(all(
478 target_os = "linux",
479 any(target_arch = "aarch64", target_arch = "x86", target_arch = "x86_64")
480 ))
481))]
482compile_error!(
483 "The `tokio_taskdump` feature is only currently supported on \
484linux, on `aarch64`, `x86` and `x86_64`."
485);
486
487// Includes re-exports used by macros.
488//
489// This module is not intended to be part of the public API. In general, any
490// `doc(hidden)` code is not part of Tokio's public and stable API.
491#[macro_use]
492#[doc(hidden)]
493pub mod macros;
494
495cfg_fs! {
496 pub mod fs;
497}
498
499mod future;
500
501pub mod io;
502pub mod net;
503
504mod loom;
505
506cfg_process! {
507 pub mod process;
508}
509
510#[cfg(any(
511 feature = "fs",
512 feature = "io-std",
513 feature = "net",
514 all(windows, feature = "process"),
515))]
516mod blocking;
517
518cfg_rt! {
519 pub mod runtime;
520}
521cfg_not_rt! {
522 pub(crate) mod runtime;
523}
524
525cfg_signal! {
526 pub mod signal;
527}
528
529cfg_signal_internal! {
530 #[cfg(not(feature = "signal"))]
531 #[allow(dead_code)]
532 #[allow(unreachable_pub)]
533 pub(crate) mod signal;
534}
535
536cfg_sync! {
537 pub mod sync;
538}
539cfg_not_sync! {
540 mod sync;
541}
542
543pub mod task;
544cfg_rt! {
545 pub use task::spawn;
546}
547
548cfg_time! {
549 pub mod time;
550}
551
552mod trace {
553 use std::future::Future;
554 use std::pin::Pin;
555 use std::task::{Context, Poll};
556
557 cfg_taskdump! {
558 pub(crate) use crate::runtime::task::trace::trace_leaf;
559 }
560
561 cfg_not_taskdump! {
562 #[inline(always)]
563 #[allow(dead_code)]
564 pub(crate) fn trace_leaf(_: &mut std::task::Context<'_>) -> std::task::Poll<()> {
565 std::task::Poll::Ready(())
566 }
567 }
568
569 #[cfg_attr(not(feature = "sync"), allow(dead_code))]
570 pub(crate) fn async_trace_leaf() -> impl Future<Output = ()> {
571 struct Trace;
572
573 impl Future for Trace {
574 type Output = ();
575
576 #[inline(always)]
577 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
578 trace_leaf(cx)
579 }
580 }
581
582 Trace
583 }
584}
585
586mod util;
587
588/// Due to the `Stream` trait's inclusion in `std` landing later than Tokio's 1.0
589/// release, most of the Tokio stream utilities have been moved into the [`tokio-stream`]
590/// crate.
591///
592/// # Why was `Stream` not included in Tokio 1.0?
593///
594/// Originally, we had planned to ship Tokio 1.0 with a stable `Stream` type
595/// but unfortunately the [RFC] had not been merged in time for `Stream` to
596/// reach `std` on a stable compiler in time for the 1.0 release of Tokio. For
597/// this reason, the team has decided to move all `Stream` based utilities to
598/// the [`tokio-stream`] crate. While this is not ideal, once `Stream` has made
599/// it into the standard library and the `MSRV` period has passed, we will implement
600/// stream for our different types.
601///
602/// While this may seem unfortunate, not all is lost as you can get much of the
603/// `Stream` support with `async/await` and `while let` loops. It is also possible
604/// to create a `impl Stream` from `async fn` using the [`async-stream`] crate.
605///
606/// [`tokio-stream`]: https://docs.rs/tokio-stream
607/// [`async-stream`]: https://docs.rs/async-stream
608/// [RFC]: https://github.com/rust-lang/rfcs/pull/2996
609///
610/// # Example
611///
612/// Convert a [`sync::mpsc::Receiver`] to an `impl Stream`.
613///
614/// ```rust,no_run
615/// use tokio::sync::mpsc;
616///
617/// let (tx, mut rx) = mpsc::channel::<usize>(16);
618///
619/// let stream = async_stream::stream! {
620/// while let Some(item) = rx.recv().await {
621/// yield item;
622/// }
623/// };
624/// ```
625pub mod stream {}
626
627// local re-exports of platform specific things, allowing for decent
628// documentation to be shimmed in on docs.rs
629
630#[cfg(docsrs)]
631pub mod doc;
632
633#[cfg(docsrs)]
634#[allow(unused)]
635pub(crate) use self::doc::os;
636
637#[cfg(not(docsrs))]
638#[allow(unused)]
639pub(crate) use std::os;
640
641cfg_macros! {
642 /// Implementation detail of the `select!` macro. This macro is **not**
643 /// intended to be used as part of the public API and is permitted to
644 /// change.
645 #[doc(hidden)]
646 pub use tokio_macros::select_priv_declare_output_enum;
647
648 /// Implementation detail of the `select!` macro. This macro is **not**
649 /// intended to be used as part of the public API and is permitted to
650 /// change.
651 #[doc(hidden)]
652 pub use tokio_macros::select_priv_clean_pattern;
653
654 cfg_rt! {
655 #[cfg(feature = "rt-multi-thread")]
656 #[cfg(not(test))] // Work around for rust-lang/rust#62127
657 #[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
658 #[doc(inline)]
659 pub use tokio_macros::main;
660
661 #[cfg(feature = "rt-multi-thread")]
662 #[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
663 #[doc(inline)]
664 pub use tokio_macros::test;
665
666 cfg_not_rt_multi_thread! {
667 #[cfg(not(test))] // Work around for rust-lang/rust#62127
668 #[doc(inline)]
669 pub use tokio_macros::main_rt as main;
670
671 #[doc(inline)]
672 pub use tokio_macros::test_rt as test;
673 }
674 }
675
676 // Always fail if rt is not enabled.
677 cfg_not_rt! {
678 #[cfg(not(test))]
679 #[doc(inline)]
680 pub use tokio_macros::main_fail as main;
681
682 #[doc(inline)]
683 pub use tokio_macros::test_fail as test;
684 }
685}
686
687// TODO: rm
688#[cfg(feature = "io-util")]
689#[cfg(test)]
690fn is_unpin<T: Unpin>() {}
691
692/// fuzz test (`fuzz_linked_list`)
693#[cfg(fuzzing)]
694pub mod fuzz;
695