From: Lucas Black Date: Fri, 26 Sep 2025 13:29:01 +0000 (-0700) Subject: ci: unfreeze wasm tests from rustc 1.88.0 (#7537) X-Git-Url: https://git.feebdaed.xyz/?a=commitdiff_plain;h=8ccf2fb92e7568bf16318dc8f3205cad14a9bc5d;p=0xmirror%2Ftokio.git ci: unfreeze wasm tests from rustc 1.88.0 (#7537) --- diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 61211420..911600f9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -988,10 +988,10 @@ jobs: features: "macros sync time rt" steps: - uses: actions/checkout@v5 - - name: Install Rust 1.88.0 + - name: Install Rust ${{ env.rust_stable }} uses: dtolnay/rust-toolchain@stable with: - toolchain: 1.88.0 + toolchain: ${{ env.rust_stable }} - name: Install wasm-pack uses: taiki-e/install-action@wasm-pack @@ -1011,10 +1011,10 @@ jobs: - wasm32-wasip1-threads steps: - uses: actions/checkout@v4 - - name: Install Rust 1.88.0 + - name: Install Rust ${{ env.rust_stable }} uses: dtolnay/rust-toolchain@stable with: - toolchain: 1.88.0 + toolchain: ${{ env.rust_stable }} targets: ${{ matrix.target }} # Install dependencies @@ -1025,11 +1025,14 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: WASI test tokio full - run: cargo test -p tokio --target ${{ matrix.target }} --features full + run: cargo test -p tokio --target ${{ matrix.target }} --features "sync,macros,io-util,rt,time" env: CARGO_TARGET_WASM32_WASIP1_RUNNER: "wasmtime run --" CARGO_TARGET_WASM32_WASIP1_THREADS_RUNNER: "wasmtime run -W bulk-memory=y -W threads=y -S threads=y --" RUSTFLAGS: --cfg tokio_unstable -Dwarnings -C target-feature=+atomics,+bulk-memory -C link-args=--max-memory=67108864 + # in order to run doctests for unstable features, we must also pass + # the unstable cfg to RustDoc + RUSTDOCFLAGS: --cfg tokio_unstable - name: WASI test tokio-util full run: cargo test -p tokio-util --target ${{ matrix.target }} --features full diff --git a/tokio-stream/src/empty.rs b/tokio-stream/src/empty.rs index 965dcf5d..85d70079 100644 --- a/tokio-stream/src/empty.rs +++ b/tokio-stream/src/empty.rs @@ -26,12 +26,12 @@ unsafe impl Sync for Empty {} /// ``` /// use tokio_stream::{self as stream, StreamExt}; /// -/// #[tokio::main] -/// async fn main() { -/// let mut none = stream::empty::(); +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// let mut none = stream::empty::(); /// -/// assert_eq!(None, none.next().await); -/// } +/// assert_eq!(None, none.next().await); +/// # } /// ``` pub const fn empty() -> Empty { Empty(PhantomData) diff --git a/tokio-stream/src/lib.rs b/tokio-stream/src/lib.rs index 28fa22a2..a5b3a05e 100644 --- a/tokio-stream/src/lib.rs +++ b/tokio-stream/src/lib.rs @@ -34,14 +34,14 @@ //! ```rust //! use tokio_stream::{self as stream, StreamExt}; //! -//! #[tokio::main] -//! async fn main() { -//! let mut stream = stream::iter(vec![0, 1, 2]); +//! # #[tokio::main(flavor = "current_thread")] +//! # async fn main() { +//! let mut stream = stream::iter(vec![0, 1, 2]); //! -//! while let Some(value) = stream.next().await { -//! println!("Got {}", value); -//! } +//! while let Some(value) = stream.next().await { +//! println!("Got {}", value); //! } +//! # } //! ``` //! //! # Returning a Stream from a function diff --git a/tokio-stream/src/once.rs b/tokio-stream/src/once.rs index c5b19bcc..ccde6281 100644 --- a/tokio-stream/src/once.rs +++ b/tokio-stream/src/once.rs @@ -22,16 +22,16 @@ impl Unpin for Once {} /// ``` /// use tokio_stream::{self as stream, StreamExt}; /// -/// #[tokio::main] -/// async fn main() { -/// // one is the loneliest number -/// let mut one = stream::once(1); +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// // one is the loneliest number +/// let mut one = stream::once(1); /// -/// assert_eq!(Some(1), one.next().await); +/// assert_eq!(Some(1), one.next().await); /// -/// // just one, that's all we get -/// assert_eq!(None, one.next().await); -/// } +/// // just one, that's all we get +/// assert_eq!(None, one.next().await); +/// # } /// ``` pub fn once(value: T) -> Once { Once { diff --git a/tokio-stream/src/stream_close.rs b/tokio-stream/src/stream_close.rs index 735acf09..f9b2f1ad 100644 --- a/tokio-stream/src/stream_close.rs +++ b/tokio-stream/src/stream_close.rs @@ -17,20 +17,20 @@ pin_project! { /// ``` /// use tokio_stream::{StreamExt, StreamMap, StreamNotifyClose}; /// - /// #[tokio::main] - /// async fn main() { - /// let mut map = StreamMap::new(); - /// let stream = StreamNotifyClose::new(tokio_stream::iter(vec![0, 1])); - /// let stream2 = StreamNotifyClose::new(tokio_stream::iter(vec![0, 1])); - /// map.insert(0, stream); - /// map.insert(1, stream2); - /// while let Some((key, val)) = map.next().await { - /// match val { - /// Some(val) => println!("got {val:?} from stream {key:?}"), - /// None => println!("stream {key:?} closed"), - /// } + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let mut map = StreamMap::new(); + /// let stream = StreamNotifyClose::new(tokio_stream::iter(vec![0, 1])); + /// let stream2 = StreamNotifyClose::new(tokio_stream::iter(vec![0, 1])); + /// map.insert(0, stream); + /// map.insert(1, stream2); + /// while let Some((key, val)) = map.next().await { + /// match val { + /// Some(val) => println!("got {val:?} from stream {key:?}"), + /// None => println!("stream {key:?} closed"), /// } /// } + /// # } /// ``` #[must_use = "streams do nothing unless polled"] pub struct StreamNotifyClose { diff --git a/tokio-stream/src/stream_ext.rs b/tokio-stream/src/stream_ext.rs index cdbada30..7e915d99 100644 --- a/tokio-stream/src/stream_ext.rs +++ b/tokio-stream/src/stream_ext.rs @@ -129,7 +129,7 @@ pub trait StreamExt: Stream { /// # Examples /// /// ``` - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// use tokio_stream::{self as stream, StreamExt}; /// @@ -171,8 +171,9 @@ pub trait StreamExt: Stream { /// # Examples /// /// ``` - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { + /// /// use tokio_stream::{self as stream, StreamExt}; /// /// let mut stream = stream::iter(vec![Ok(1), Ok(2), Err("nope")]); @@ -203,7 +204,7 @@ pub trait StreamExt: Stream { /// # Examples /// /// ``` - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// use tokio_stream::{self as stream, StreamExt}; /// @@ -239,7 +240,7 @@ pub trait StreamExt: Stream { /// # Examples /// /// ``` - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// use tokio_stream::{self as stream, StreamExt}; /// @@ -283,7 +284,7 @@ pub trait StreamExt: Stream { /// # Examples /// /// ``` - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// use tokio_stream::{self as stream, StreamExt}; /// @@ -418,7 +419,7 @@ pub trait StreamExt: Stream { /// # Examples /// /// ``` - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// use tokio_stream::{self as stream, StreamExt}; /// @@ -454,7 +455,7 @@ pub trait StreamExt: Stream { /// /// # Examples /// ``` - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// use tokio_stream::{self as stream, StreamExt}; /// @@ -514,7 +515,10 @@ pub trait StreamExt: Stream { /// } /// } /// + /// # /* /// #[tokio::main] + /// # */ + /// # #[tokio::main(flavor = "current_thread")] /// async fn main() { /// let mut stream = Alternate { state: 0 }; /// @@ -551,7 +555,7 @@ pub trait StreamExt: Stream { /// # Examples /// /// ``` - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// use tokio_stream::{self as stream, StreamExt}; /// @@ -580,7 +584,7 @@ pub trait StreamExt: Stream { /// # Examples /// /// ``` - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// use tokio_stream::{self as stream, StreamExt}; /// @@ -606,7 +610,7 @@ pub trait StreamExt: Stream { /// # Examples /// /// ``` - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// use tokio_stream::{self as stream, StreamExt}; /// @@ -637,7 +641,7 @@ pub trait StreamExt: Stream { /// # Examples /// /// ``` - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// use tokio_stream::{self as stream, StreamExt}; /// let mut stream = stream::iter(vec![1,2,3,4,1]).skip_while(|x| *x < 3); @@ -680,7 +684,7 @@ pub trait StreamExt: Stream { /// Basic usage: /// /// ``` - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// use tokio_stream::{self as stream, StreamExt}; /// @@ -695,7 +699,7 @@ pub trait StreamExt: Stream { /// Stopping at the first `false`: /// /// ``` - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// use tokio_stream::{self as stream, StreamExt}; /// @@ -739,7 +743,7 @@ pub trait StreamExt: Stream { /// Basic usage: /// /// ``` - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// use tokio_stream::{self as stream, StreamExt}; /// @@ -754,7 +758,7 @@ pub trait StreamExt: Stream { /// Stopping at the first `true`: /// /// ``` - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// use tokio_stream::{self as stream, StreamExt}; /// @@ -787,21 +791,21 @@ pub trait StreamExt: Stream { /// ``` /// use tokio_stream::{self as stream, StreamExt}; /// - /// #[tokio::main] - /// async fn main() { - /// let one = stream::iter(vec![1, 2, 3]); - /// let two = stream::iter(vec![4, 5, 6]); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let one = stream::iter(vec![1, 2, 3]); + /// let two = stream::iter(vec![4, 5, 6]); /// - /// let mut stream = one.chain(two); + /// let mut stream = one.chain(two); /// - /// assert_eq!(stream.next().await, Some(1)); - /// assert_eq!(stream.next().await, Some(2)); - /// assert_eq!(stream.next().await, Some(3)); - /// assert_eq!(stream.next().await, Some(4)); - /// assert_eq!(stream.next().await, Some(5)); - /// assert_eq!(stream.next().await, Some(6)); - /// assert_eq!(stream.next().await, None); - /// } + /// assert_eq!(stream.next().await, Some(1)); + /// assert_eq!(stream.next().await, Some(2)); + /// assert_eq!(stream.next().await, Some(3)); + /// assert_eq!(stream.next().await, Some(4)); + /// assert_eq!(stream.next().await, Some(5)); + /// assert_eq!(stream.next().await, Some(6)); + /// assert_eq!(stream.next().await, None); + /// # } /// ``` fn chain(self, other: U) -> Chain where @@ -823,7 +827,7 @@ pub trait StreamExt: Stream { /// # Examples /// Basic usage: /// ``` - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// use tokio_stream::{self as stream, *}; /// @@ -874,16 +878,16 @@ pub trait StreamExt: Stream { /// ``` /// use tokio_stream::{self as stream, StreamExt}; /// - /// #[tokio::main] - /// async fn main() { - /// let doubled: Vec = - /// stream::iter(vec![1, 2, 3]) - /// .map(|x| x * 2) - /// .collect() - /// .await; + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let doubled: Vec = + /// stream::iter(vec![1, 2, 3]) + /// .map(|x| x * 2) + /// .collect() + /// .await; /// - /// assert_eq!(vec![2, 4, 6], doubled); - /// } + /// assert_eq!(vec![2, 4, 6], doubled); + /// # } /// ``` /// /// Collecting a stream of `Result` values @@ -891,26 +895,26 @@ pub trait StreamExt: Stream { /// ``` /// use tokio_stream::{self as stream, StreamExt}; /// - /// #[tokio::main] - /// async fn main() { - /// // A stream containing only `Ok` values will be collected - /// let values: Result, &str> = - /// stream::iter(vec![Ok(1), Ok(2), Ok(3)]) - /// .collect() - /// .await; + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// // A stream containing only `Ok` values will be collected + /// let values: Result, &str> = + /// stream::iter(vec![Ok(1), Ok(2), Ok(3)]) + /// .collect() + /// .await; /// - /// assert_eq!(Ok(vec![1, 2, 3]), values); + /// assert_eq!(Ok(vec![1, 2, 3]), values); /// - /// // A stream containing `Err` values will return the first error. - /// let results = vec![Ok(1), Err("no"), Ok(2), Ok(3), Err("nein")]; + /// // A stream containing `Err` values will return the first error. + /// let results = vec![Ok(1), Err("no"), Ok(2), Ok(3), Err("nein")]; /// - /// let values: Result, &str> = - /// stream::iter(results) - /// .collect() - /// .await; + /// let values: Result, &str> = + /// stream::iter(results) + /// .collect() + /// .await; /// - /// assert_eq!(Err("no"), values); - /// } + /// assert_eq!(Err("no"), values); + /// # } /// ``` fn collect(self) -> Collect where @@ -945,7 +949,7 @@ pub trait StreamExt: Stream { /// Suppose we have a stream `int_stream` that yields 3 numbers (1, 2, 3): /// /// ``` - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// use tokio_stream::{self as stream, StreamExt}; /// use std::time::Duration; @@ -1031,7 +1035,7 @@ pub trait StreamExt: Stream { /// Suppose we have a stream `int_stream` that yields 3 numbers (1, 2, 3): /// /// ``` - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// use tokio_stream::{self as stream, StreamExt}; /// use std::time::Duration; diff --git a/tokio-stream/src/stream_map.rs b/tokio-stream/src/stream_map.rs index f276f992..49ccc926 100644 --- a/tokio-stream/src/stream_map.rs +++ b/tokio-stream/src/stream_map.rs @@ -65,57 +65,57 @@ use std::task::{ready, Context, Poll}; /// use tokio::sync::mpsc; /// use std::pin::Pin; /// -/// #[tokio::main] -/// async fn main() { -/// let (tx1, mut rx1) = mpsc::channel::(10); -/// let (tx2, mut rx2) = mpsc::channel::(10); -/// -/// // Convert the channels to a `Stream`. -/// let rx1 = Box::pin(async_stream::stream! { -/// while let Some(item) = rx1.recv().await { -/// yield item; -/// } -/// }) as Pin + Send>>; -/// -/// let rx2 = Box::pin(async_stream::stream! { -/// while let Some(item) = rx2.recv().await { -/// yield item; -/// } -/// }) as Pin + Send>>; -/// -/// tokio::spawn(async move { -/// tx1.send(1).await.unwrap(); -/// -/// // This value will never be received. The send may or may not return -/// // `Err` depending on if the remote end closed first or not. -/// let _ = tx1.send(2).await; -/// }); -/// -/// tokio::spawn(async move { -/// tx2.send(3).await.unwrap(); -/// let _ = tx2.send(4).await; -/// }); -/// -/// let mut map = StreamMap::new(); -/// -/// // Insert both streams -/// map.insert("one", rx1); -/// map.insert("two", rx2); -/// -/// // Read twice -/// for _ in 0..2 { -/// let (key, val) = map.next().await.unwrap(); -/// -/// if key == "one" { -/// assert_eq!(val, 1); -/// } else { -/// assert_eq!(val, 3); -/// } +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// let (tx1, mut rx1) = mpsc::channel::(10); +/// let (tx2, mut rx2) = mpsc::channel::(10); +/// +/// // Convert the channels to a `Stream`. +/// let rx1 = Box::pin(async_stream::stream! { +/// while let Some(item) = rx1.recv().await { +/// yield item; +/// } +/// }) as Pin + Send>>; +/// +/// let rx2 = Box::pin(async_stream::stream! { +/// while let Some(item) = rx2.recv().await { +/// yield item; +/// } +/// }) as Pin + Send>>; +/// +/// tokio::spawn(async move { +/// tx1.send(1).await.unwrap(); +/// +/// // This value will never be received. The send may or may not return +/// // `Err` depending on if the remote end closed first or not. +/// let _ = tx1.send(2).await; +/// }); /// -/// // Remove the stream to prevent reading the next value -/// map.remove(key); +/// tokio::spawn(async move { +/// tx2.send(3).await.unwrap(); +/// let _ = tx2.send(4).await; +/// }); +/// +/// let mut map = StreamMap::new(); +/// +/// // Insert both streams +/// map.insert("one", rx1); +/// map.insert("two", rx2); +/// +/// // Read twice +/// for _ in 0..2 { +/// let (key, val) = map.next().await.unwrap(); +/// +/// if key == "one" { +/// assert_eq!(val, 1); +/// } else { +/// assert_eq!(val, 3); /// } +/// +/// // Remove the stream to prevent reading the next value +/// map.remove(key); /// } +/// # } /// ``` /// /// This example models a read-only client to a chat system with channels. The @@ -185,20 +185,20 @@ use std::task::{ready, Context, Poll}; /// ``` /// use tokio_stream::{StreamExt, StreamMap, StreamNotifyClose}; /// -/// #[tokio::main] -/// async fn main() { -/// let mut map = StreamMap::new(); -/// let stream = StreamNotifyClose::new(tokio_stream::iter(vec![0, 1])); -/// let stream2 = StreamNotifyClose::new(tokio_stream::iter(vec![0, 1])); -/// map.insert(0, stream); -/// map.insert(1, stream2); -/// while let Some((key, val)) = map.next().await { -/// match val { -/// Some(val) => println!("got {val:?} from stream {key:?}"), -/// None => println!("stream {key:?} closed"), -/// } +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// let mut map = StreamMap::new(); +/// let stream = StreamNotifyClose::new(tokio_stream::iter(vec![0, 1])); +/// let stream2 = StreamNotifyClose::new(tokio_stream::iter(vec![0, 1])); +/// map.insert(0, stream); +/// map.insert(1, stream2); +/// while let Some((key, val)) = map.next().await { +/// match val { +/// Some(val) => println!("got {val:?} from stream {key:?}"), +/// None => println!("stream {key:?} closed"), /// } /// } +/// # } /// ``` #[derive(Debug)] diff --git a/tokio-stream/src/wrappers/tcp_listener.rs b/tokio-stream/src/wrappers/tcp_listener.rs index feb6405b..c589dd90 100644 --- a/tokio-stream/src/wrappers/tcp_listener.rs +++ b/tokio-stream/src/wrappers/tcp_listener.rs @@ -11,6 +11,8 @@ use tokio::net::{TcpListener, TcpStream}; /// Accept connections from both IPv4 and IPv6 listeners in the same loop: /// /// ```no_run +/// # #[cfg(not(target_family = "wasm"))] +/// # { /// use std::net::{Ipv4Addr, Ipv6Addr}; /// /// use tokio::net::TcpListener; @@ -31,6 +33,7 @@ use tokio::net::{TcpListener, TcpStream}; /// } /// # Ok(()) /// # } +/// # } /// ``` /// /// [`TcpListener`]: struct@tokio::net::TcpListener diff --git a/tokio-stream/src/wrappers/watch.rs b/tokio-stream/src/wrappers/watch.rs index a1e4fbfa..e5eb47ef 100644 --- a/tokio-stream/src/wrappers/watch.rs +++ b/tokio-stream/src/wrappers/watch.rs @@ -17,7 +17,7 @@ use tokio::sync::watch::error::RecvError; /// # Examples /// /// ``` -/// # #[tokio::main] +/// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// use tokio_stream::{StreamExt, wrappers::WatchStream}; /// use tokio::sync::watch; @@ -33,7 +33,7 @@ use tokio::sync::watch::error::RecvError; /// ``` /// /// ``` -/// # #[tokio::main] +/// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// use tokio_stream::{StreamExt, wrappers::WatchStream}; /// use tokio::sync::watch; @@ -51,7 +51,7 @@ use tokio::sync::watch::error::RecvError; /// Example with [`WatchStream::from_changes`]: /// /// ``` -/// # #[tokio::main] +/// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// use futures::future::FutureExt; /// use tokio::sync::watch; diff --git a/tokio-util/src/codec/length_delimited.rs b/tokio-util/src/codec/length_delimited.rs index fed49ca8..ff40fe49 100644 --- a/tokio-util/src/codec/length_delimited.rs +++ b/tokio-util/src/codec/length_delimited.rs @@ -81,7 +81,7 @@ //! ``` //! # use tokio_stream::StreamExt; //! # use tokio_util::codec::LengthDelimitedCodec; -//! # #[tokio::main] +//! # #[tokio::main(flavor = "current_thread")] //! # async fn main() { //! # let io: &[u8] = b"\x00\x0BHello world"; //! let mut reader = LengthDelimitedCodec::builder() @@ -117,7 +117,7 @@ //! ``` //! # use tokio_stream::StreamExt; //! # use tokio_util::codec::LengthDelimitedCodec; -//! # #[tokio::main] +//! # #[tokio::main(flavor = "current_thread")] //! # async fn main() { //! # let io: &[u8] = b"\x00\x0BHello world"; //! let mut reader = LengthDelimitedCodec::builder() @@ -154,7 +154,7 @@ //! ``` //! # use tokio_stream::StreamExt; //! # use tokio_util::codec::LengthDelimitedCodec; -//! # #[tokio::main] +//! # #[tokio::main(flavor = "current_thread")] //! # async fn main() { //! # let io: &[u8] = b"\x00\x0DHello world"; //! let mut reader = LengthDelimitedCodec::builder() @@ -190,7 +190,7 @@ //! ``` //! # use tokio_stream::StreamExt; //! # use tokio_util::codec::LengthDelimitedCodec; -//! # #[tokio::main] +//! # #[tokio::main(flavor = "current_thread")] //! # async fn main() { //! # let io: &[u8] = b"\x00\x00\x0B\xCA\xFEHello world"; //! let mut reader = LengthDelimitedCodec::builder() @@ -237,7 +237,7 @@ //! ``` //! # use tokio_stream::StreamExt; //! # use tokio_util::codec::LengthDelimitedCodec; -//! # #[tokio::main] +//! # #[tokio::main(flavor = "current_thread")] //! # async fn main() { //! # let io: &[u8] = b"\xCA\x00\x0B\xFEHello world"; //! let mut reader = LengthDelimitedCodec::builder() @@ -286,7 +286,7 @@ //! ``` //! # use tokio_stream::StreamExt; //! # use tokio_util::codec::LengthDelimitedCodec; -//! # #[tokio::main] +//! # #[tokio::main(flavor = "current_thread")] //! # async fn main() { //! # let io: &[u8] = b"\xCA\x00\x0F\xFEHello world"; //! let mut reader = LengthDelimitedCodec::builder() @@ -329,7 +329,7 @@ //! ``` //! # use tokio_stream::StreamExt; //! # use tokio_util::codec::LengthDelimitedCodec; -//! # #[tokio::main] +//! # #[tokio::main(flavor = "current_thread")] //! # async fn main() { //! # let io: &[u8] = b"\x00\x00\x0B\xFFHello world"; //! let mut reader = LengthDelimitedCodec::builder() diff --git a/tokio-util/src/codec/mod.rs b/tokio-util/src/codec/mod.rs index 11f44133..a03c0b94 100644 --- a/tokio-util/src/codec/mod.rs +++ b/tokio-util/src/codec/mod.rs @@ -19,25 +19,25 @@ //! use tokio_util::codec::LinesCodec; //! use tokio_util::codec::FramedWrite; //! -//! #[tokio::main] -//! async fn main() { -//! let buffer = Vec::new(); -//! let messages = vec!["Hello", "World"]; -//! let encoder = LinesCodec::new(); +//! # #[tokio::main(flavor = "current_thread")] +//! # async fn main() { +//! let buffer = Vec::new(); +//! let messages = vec!["Hello", "World"]; +//! let encoder = LinesCodec::new(); //! -//! // FramedWrite is a sink which means you can send values into it -//! // asynchronously. -//! let mut writer = FramedWrite::new(buffer, encoder); +//! // FramedWrite is a sink which means you can send values into it +//! // asynchronously. +//! let mut writer = FramedWrite::new(buffer, encoder); //! -//! // To be able to send values into a FramedWrite, you need to bring the -//! // `SinkExt` trait into scope. -//! writer.send(messages[0]).await.unwrap(); -//! writer.send(messages[1]).await.unwrap(); +//! // To be able to send values into a FramedWrite, you need to bring the +//! // `SinkExt` trait into scope. +//! writer.send(messages[0]).await.unwrap(); +//! writer.send(messages[1]).await.unwrap(); //! -//! let buffer = writer.get_ref(); +//! let buffer = writer.get_ref(); //! -//! assert_eq!(buffer.as_slice(), "Hello\nWorld\n".as_bytes()); -//! } +//! assert_eq!(buffer.as_slice(), "Hello\nWorld\n".as_bytes()); +//! # } //!``` //! //! # Example decoding using `LinesCodec` @@ -51,25 +51,25 @@ //! use tokio_util::codec::LinesCodec; //! use tokio_util::codec::FramedRead; //! -//! #[tokio::main] -//! async fn main() { -//! let message = "Hello\nWorld".as_bytes(); -//! let decoder = LinesCodec::new(); +//! # #[tokio::main(flavor = "current_thread")] +//! # async fn main() { +//! let message = "Hello\nWorld".as_bytes(); +//! let decoder = LinesCodec::new(); //! -//! // FramedRead can be used to read a stream of values that are framed according to -//! // a codec. FramedRead will read from its input (here `buffer`) until a whole frame -//! // can be parsed. -//! let mut reader = FramedRead::new(message, decoder); +//! // FramedRead can be used to read a stream of values that are framed according to +//! // a codec. FramedRead will read from its input (here `buffer`) until a whole frame +//! // can be parsed. +//! let mut reader = FramedRead::new(message, decoder); //! -//! // To read values from a FramedRead, you need to bring the -//! // `StreamExt` trait into scope. -//! let frame1 = reader.next().await.unwrap().unwrap(); -//! let frame2 = reader.next().await.unwrap().unwrap(); +//! // To read values from a FramedRead, you need to bring the +//! // `StreamExt` trait into scope. +//! let frame1 = reader.next().await.unwrap().unwrap(); +//! let frame2 = reader.next().await.unwrap().unwrap(); //! -//! assert!(reader.next().await.is_none()); -//! assert_eq!(frame1, "Hello"); -//! assert_eq!(frame2, "World"); -//! } +//! assert!(reader.next().await.is_none()); +//! assert_eq!(frame1, "Hello"); +//! assert_eq!(frame2, "World"); +//! # } //! ``` //! //! # The Decoder trait diff --git a/tokio-util/src/compat.rs b/tokio-util/src/compat.rs index 9e3f26bd..c68b864c 100644 --- a/tokio-util/src/compat.rs +++ b/tokio-util/src/compat.rs @@ -34,6 +34,8 @@ //! stream via [`compat()`]. //! //! ```no_run +//! # #[cfg(not(target_family = "wasm"))] +//! # { //! use tokio::net::{TcpListener, TcpStream}; //! use tokio::io::AsyncWriteExt; //! use tokio_util::compat::TokioAsyncReadCompatExt; @@ -58,6 +60,7 @@ //! //! Ok(()) //! } +//! # } //! ``` //! //! ## Example 2: Futures -> Tokio (`AsyncRead`) @@ -66,6 +69,8 @@ //! adapt it to be used with [`tokio::io::AsyncReadExt::read_to_end`] //! //! ``` +//! # #[cfg(not(target_family = "wasm"))] +//! # { //! use futures::io::Cursor; //! use tokio_util::compat::FuturesAsyncReadCompatExt; //! use tokio::io::AsyncReadExt; @@ -82,6 +87,7 @@ //! // Run the future inside a Tokio runtime //! tokio::runtime::Runtime::new().unwrap().block_on(future); //! } +//! # } //! ``` //! //! ## Common Use Cases diff --git a/tokio-util/src/context.rs b/tokio-util/src/context.rs index a7a5e029..c4d57286 100644 --- a/tokio-util/src/context.rs +++ b/tokio-util/src/context.rs @@ -37,6 +37,8 @@ pin_project! { /// them. It then uses the context of the runtime with the timer enabled to /// execute a [`sleep`] future on the runtime with timing disabled. /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::time::{sleep, Duration}; /// use tokio_util::context::RuntimeExt; /// @@ -56,6 +58,7 @@ pin_project! { /// /// // Execute the future on rt2. /// rt2.block_on(fut); + /// # } /// ``` /// /// [`Handle`]: struct@tokio::runtime::Handle @@ -88,6 +91,8 @@ impl TokioContext { /// [`RuntimeExt::wrap`]: fn@RuntimeExt::wrap /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::time::{sleep, Duration}; /// use tokio_util::context::TokioContext; /// @@ -109,6 +114,7 @@ impl TokioContext { /// /// // Execute the future on rt2. /// rt2.block_on(fut); + /// # } /// ``` pub fn new(future: F, handle: Handle) -> TokioContext { TokioContext { @@ -153,6 +159,8 @@ pub trait RuntimeExt { /// execute a [`sleep`] future on the runtime with timing disabled. /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::time::{sleep, Duration}; /// use tokio_util::context::RuntimeExt; /// @@ -172,6 +180,7 @@ pub trait RuntimeExt { /// /// // Execute the future on rt2. /// rt2.block_on(fut); + /// # } /// ``` /// /// [`TokioContext`]: struct@crate::context::TokioContext diff --git a/tokio-util/src/either.rs b/tokio-util/src/either.rs index f661bb9e..9e4c34fa 100644 --- a/tokio-util/src/either.rs +++ b/tokio-util/src/either.rs @@ -46,18 +46,18 @@ use tokio::io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, ReadBuf, Result} /// # async fn some_async_function() -> u32 { 10 } /// # async fn other_async_function() -> u32 { 20 } /// -/// #[tokio::main] -/// async fn main() { -/// let result = if some_condition() { -/// Either::Left(some_async_function()) -/// } else { -/// Either::Right(other_async_function()) -/// }; +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// let result = if some_condition() { +/// Either::Left(some_async_function()) +/// } else { +/// Either::Right(other_async_function()) +/// }; /// -/// let value = result.await; -/// println!("Result is {}", value); -/// # assert_eq!(value, 10); -/// } +/// let value = result.await; +/// println!("Result is {}", value); +/// # assert_eq!(value, 10); +/// # } /// ``` #[allow(missing_docs)] // Doc-comments for variants in this particular case don't make much sense. #[derive(Debug, Clone)] diff --git a/tokio-util/src/io/read_arc.rs b/tokio-util/src/io/read_arc.rs index 30b87023..393b7f4f 100644 --- a/tokio-util/src/io/read_arc.rs +++ b/tokio-util/src/io/read_arc.rs @@ -10,7 +10,7 @@ use tokio::io::{AsyncRead, AsyncReadExt}; /// # Example /// /// ``` -/// # #[tokio::main] +/// # #[tokio::main(flavor = "current_thread")] /// # async fn main() -> std::io::Result<()> { /// use tokio_util::io::read_exact_arc; /// diff --git a/tokio-util/src/io/read_buf.rs b/tokio-util/src/io/read_buf.rs index d7938a3b..ddc974bf 100644 --- a/tokio-util/src/io/read_buf.rs +++ b/tokio-util/src/io/read_buf.rs @@ -16,7 +16,7 @@ use tokio::io::AsyncRead; /// use tokio_stream as stream; /// use tokio::io::Result; /// use tokio_util::io::{StreamReader, read_buf}; -/// # #[tokio::main] +/// # #[tokio::main(flavor = "current_thread")] /// # async fn main() -> std::io::Result<()> { /// /// // Create a reader from an iterator. This particular reader will always be diff --git a/tokio-util/src/io/reader_stream.rs b/tokio-util/src/io/reader_stream.rs index 866c1140..93bc594f 100644 --- a/tokio-util/src/io/reader_stream.rs +++ b/tokio-util/src/io/reader_stream.rs @@ -16,7 +16,7 @@ pin_project! { /// # Example /// /// ``` - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() -> std::io::Result<()> { /// use tokio_stream::StreamExt; /// use tokio_util::io::ReaderStream; diff --git a/tokio-util/src/io/sync_bridge.rs b/tokio-util/src/io/sync_bridge.rs index 6821c7ed..a412eb03 100644 --- a/tokio-util/src/io/sync_bridge.rs +++ b/tokio-util/src/io/sync_bridge.rs @@ -57,15 +57,15 @@ use tokio::io::{ /// let hash = blake3::hash(&data); /// /// Ok(hash) -///} -/// -/// #[tokio::main] -/// async fn main() -> Result<(), std::io::Error> { -/// // Example: In-memory data. -/// let data = b"Hello, world!"; // A byte slice. -/// let reader = Cursor::new(data); // Create an in-memory AsyncRead. -/// hash_contents(reader).await /// } +/// +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() -> Result<(), std::io::Error> { +/// // Example: In-memory data. +/// let data = b"Hello, world!"; // A byte slice. +/// let reader = Cursor::new(data); // Create an in-memory AsyncRead. +/// hash_contents(reader).await +/// # } /// ``` /// /// When the data doesn't fit into memory, the hashing library will usually @@ -88,7 +88,7 @@ use tokio::io::{ /// /// and hashes the data incrementally. /// async fn hash_stream(mut reader: impl AsyncRead + Unpin, mut hasher: Hasher) -> Result<(), std::io::Error> { /// // Create a buffer to read data into, sized for performance. -/// let mut data = vec![0; 64 * 1024]; +/// let mut data = vec![0; 16 * 1024]; /// loop { /// // Read data from the reader into the buffer. /// let len = reader.read(&mut data).await?; @@ -102,16 +102,16 @@ use tokio::io::{ /// let hash = hasher.finalize(); /// /// Ok(hash) -///} -/// -/// #[tokio::main] -/// async fn main() -> Result<(), std::io::Error> { -/// // Example: In-memory data. -/// let data = b"Hello, world!"; // A byte slice. -/// let reader = Cursor::new(data); // Create an in-memory AsyncRead. -/// let hasher = Hasher; -/// hash_stream(reader, hasher).await /// } +/// +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() -> Result<(), std::io::Error> { +/// // Example: In-memory data. +/// let data = b"Hello, world!"; // A byte slice. +/// let reader = Cursor::new(data); // Create an in-memory AsyncRead. +/// let hasher = Hasher; +/// hash_stream(reader, hasher).await +/// # } /// ``` /// /// @@ -218,6 +218,8 @@ use tokio::io::{ /// thread pool, preventing it from interfering with the async tasks. /// /// ```rust +/// # #[cfg(not(target_family = "wasm"))] +/// # { /// use tokio::task::spawn_blocking; /// use tokio_util::io::SyncIoBridge; /// use tokio::io::AsyncRead; @@ -255,6 +257,7 @@ use tokio::io::{ /// /// Ok(()) /// } +/// # } /// ``` /// #[derive(Debug)] diff --git a/tokio-util/src/task/join_map.rs b/tokio-util/src/task/join_map.rs index ad370bea..3a5eccdc 100644 --- a/tokio-util/src/task/join_map.rs +++ b/tokio-util/src/task/join_map.rs @@ -36,28 +36,28 @@ use tokio::task::{AbortHandle, Id, JoinError, JoinSet, LocalSet}; /// ``` /// use tokio_util::task::JoinMap; /// -/// #[tokio::main] -/// async fn main() { -/// let mut map = JoinMap::new(); +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// let mut map = JoinMap::new(); /// -/// for i in 0..10 { -/// // Spawn a task on the `JoinMap` with `i` as its key. -/// map.spawn(i, async move { /* ... */ }); -/// } +/// for i in 0..10 { +/// // Spawn a task on the `JoinMap` with `i` as its key. +/// map.spawn(i, async move { /* ... */ }); +/// } /// -/// let mut seen = [false; 10]; +/// let mut seen = [false; 10]; /// -/// // When a task completes, `join_next` returns the task's key along -/// // with its output. -/// while let Some((key, res)) = map.join_next().await { -/// seen[key] = true; -/// assert!(res.is_ok(), "task {} completed successfully!", key); -/// } +/// // When a task completes, `join_next` returns the task's key along +/// // with its output. +/// while let Some((key, res)) = map.join_next().await { +/// seen[key] = true; +/// assert!(res.is_ok(), "task {} completed successfully!", key); +/// } /// -/// for i in 0..10 { -/// assert!(seen[i]); -/// } +/// for i in 0..10 { +/// assert!(seen[i]); /// } +/// # } /// ``` /// /// Cancel tasks based on their keys: @@ -65,30 +65,30 @@ use tokio::task::{AbortHandle, Id, JoinError, JoinSet, LocalSet}; /// ``` /// use tokio_util::task::JoinMap; /// -/// #[tokio::main] -/// async fn main() { -/// let mut map = JoinMap::new(); +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// let mut map = JoinMap::new(); /// -/// map.spawn("hello world", std::future::ready(1)); -/// map.spawn("goodbye world", std::future::pending()); +/// map.spawn("hello world", std::future::ready(1)); +/// map.spawn("goodbye world", std::future::pending()); /// -/// // Look up the "goodbye world" task in the map and abort it. -/// let aborted = map.abort("goodbye world"); +/// // Look up the "goodbye world" task in the map and abort it. +/// let aborted = map.abort("goodbye world"); /// -/// // `JoinMap::abort` returns `true` if a task existed for the -/// // provided key. -/// assert!(aborted); +/// // `JoinMap::abort` returns `true` if a task existed for the +/// // provided key. +/// assert!(aborted); /// -/// while let Some((key, res)) = map.join_next().await { -/// if key == "goodbye world" { -/// // The aborted task should complete with a cancelled `JoinError`. -/// assert!(res.unwrap_err().is_cancelled()); -/// } else { -/// // Other tasks should complete normally. -/// assert_eq!(res.unwrap(), 1); -/// } +/// while let Some((key, res)) = map.join_next().await { +/// if key == "goodbye world" { +/// // The aborted task should complete with a cancelled `JoinError`. +/// assert!(res.unwrap_err().is_cancelled()); +/// } else { +/// // Other tasks should complete normally. +/// assert_eq!(res.unwrap(), 1); /// } /// } +/// # } /// ``` /// /// [`JoinSet`]: tokio::task::JoinSet @@ -186,7 +186,7 @@ impl JoinMap { /// # Examples /// /// ``` - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// use tokio_util::task::JoinMap; /// use std::collections::hash_map::RandomState; @@ -521,7 +521,7 @@ where /// ``` /// use tokio_util::task::JoinMap; /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let mut map = JoinMap::new(); /// @@ -686,7 +686,7 @@ where /// # Examples /// /// ``` - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// use tokio_util::task::JoinMap; /// @@ -715,7 +715,7 @@ where /// # Examples /// /// ``` - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// use tokio_util::task::JoinMap; /// diff --git a/tokio-util/src/task/spawn_pinned.rs b/tokio-util/src/task/spawn_pinned.rs index 177ea028..3f692d3c 100644 --- a/tokio-util/src/task/spawn_pinned.rs +++ b/tokio-util/src/task/spawn_pinned.rs @@ -22,6 +22,8 @@ use tokio::task::{spawn_local, JoinHandle, LocalSet}; /// # Examples /// /// ``` +/// # #[cfg(not(target_family = "wasm"))] +/// # { /// use std::rc::Rc; /// use tokio::task; /// use tokio_util::task::LocalPoolHandle; @@ -45,6 +47,7 @@ use tokio::task::{spawn_local, JoinHandle, LocalSet}; /// }).await.unwrap(); /// println!("output: {}", output); /// } +/// # } /// ``` /// #[derive(Clone)] @@ -94,6 +97,8 @@ impl LocalPoolHandle { /// /// # Examples /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use std::rc::Rc; /// use tokio_util::task::LocalPoolHandle; /// @@ -116,6 +121,7 @@ impl LocalPoolHandle { /// /// assert_eq!(output, "test"); /// } + /// # } /// ``` pub fn spawn_pinned(&self, create_task: F) -> JoinHandle where @@ -144,6 +150,8 @@ impl LocalPoolHandle { /// This method can be used to spawn a task on all worker threads of the pool: /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio_util::task::LocalPoolHandle; /// /// #[tokio::main] @@ -167,6 +175,7 @@ impl LocalPoolHandle { /// handle.await.unwrap(); /// } /// } + /// # } /// ``` /// #[track_caller] diff --git a/tokio-util/src/task/task_tracker.rs b/tokio-util/src/task/task_tracker.rs index 682ebf35..e168baa4 100644 --- a/tokio-util/src/task/task_tracker.rs +++ b/tokio-util/src/task/task_tracker.rs @@ -66,23 +66,23 @@ use tokio::{ /// ``` /// use tokio_util::task::TaskTracker; /// -/// #[tokio::main] -/// async fn main() { -/// let tracker = TaskTracker::new(); +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// let tracker = TaskTracker::new(); /// -/// for i in 0..10 { -/// tracker.spawn(async move { -/// println!("Task {} is running!", i); -/// }); -/// } -/// // Once we spawned everything, we close the tracker. -/// tracker.close(); +/// for i in 0..10 { +/// tracker.spawn(async move { +/// println!("Task {} is running!", i); +/// }); +/// } +/// // Once we spawned everything, we close the tracker. +/// tracker.close(); /// -/// // Wait for everything to finish. -/// tracker.wait().await; +/// // Wait for everything to finish. +/// tracker.wait().await; /// -/// println!("This is printed after all of the tasks."); -/// } +/// println!("This is printed after all of the tasks."); +/// # } /// ``` /// /// ## Wait for tasks to exit diff --git a/tokio-util/src/time/delay_queue.rs b/tokio-util/src/time/delay_queue.rs index eff8cb1a..3f0bc58c 100644 --- a/tokio-util/src/time/delay_queue.rs +++ b/tokio-util/src/time/delay_queue.rs @@ -461,7 +461,7 @@ impl DelayQueue { /// # use tokio_util::time::DelayQueue; /// # use std::time::Duration; /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let mut delay_queue = DelayQueue::with_capacity(10); /// @@ -517,7 +517,7 @@ impl DelayQueue { /// use tokio::time::{Duration, Instant}; /// use tokio_util::time::DelayQueue; /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let mut delay_queue = DelayQueue::new(); /// let key = delay_queue.insert_at( @@ -637,7 +637,7 @@ impl DelayQueue { /// use tokio_util::time::DelayQueue; /// use std::time::Duration; /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let mut delay_queue = DelayQueue::new(); /// let key = delay_queue.insert("foo", Duration::from_secs(5)); @@ -692,7 +692,7 @@ impl DelayQueue { /// use tokio_util::time::DelayQueue; /// use std::time::Duration; /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let mut delay_queue = DelayQueue::new(); /// @@ -743,7 +743,7 @@ impl DelayQueue { /// use tokio_util::time::DelayQueue; /// use std::time::Duration; /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let mut delay_queue = DelayQueue::new(); /// let key = delay_queue.insert("foo", Duration::from_secs(5)); @@ -841,7 +841,7 @@ impl DelayQueue { /// use tokio::time::{Duration, Instant}; /// use tokio_util::time::DelayQueue; /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let mut delay_queue = DelayQueue::new(); /// let key = delay_queue.insert("foo", Duration::from_secs(5)); @@ -898,7 +898,7 @@ impl DelayQueue { /// use tokio_util::time::DelayQueue; /// use std::time::Duration; /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let mut delay_queue = DelayQueue::with_capacity(10); /// @@ -931,7 +931,7 @@ impl DelayQueue { /// use tokio_util::time::DelayQueue; /// use std::time::Duration; /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let mut delay_queue = DelayQueue::new(); /// @@ -983,7 +983,7 @@ impl DelayQueue { /// use tokio_util::time::DelayQueue; /// use std::time::Duration; /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let mut delay_queue = DelayQueue::new(); /// let key = delay_queue.insert("foo", Duration::from_secs(5)); @@ -1014,7 +1014,7 @@ impl DelayQueue { /// use tokio_util::time::DelayQueue; /// use std::time::Duration; /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let mut delay_queue = DelayQueue::new(); /// @@ -1056,7 +1056,7 @@ impl DelayQueue { /// use tokio_util::time::DelayQueue; /// use std::time::Duration; /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let mut delay_queue: DelayQueue = DelayQueue::with_capacity(10); /// assert_eq!(delay_queue.len(), 0); @@ -1091,7 +1091,7 @@ impl DelayQueue { /// use tokio_util::time::DelayQueue; /// use std::time::Duration; /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let mut delay_queue = DelayQueue::new(); /// @@ -1121,7 +1121,7 @@ impl DelayQueue { /// use tokio_util::time::DelayQueue; /// use std::time::Duration; /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let mut delay_queue = DelayQueue::new(); /// assert!(delay_queue.is_empty()); diff --git a/tokio-util/src/util/poll_buf.rs b/tokio-util/src/util/poll_buf.rs index 452cc3c8..4894d164 100644 --- a/tokio-util/src/util/poll_buf.rs +++ b/tokio-util/src/util/poll_buf.rs @@ -18,7 +18,7 @@ use std::task::{ready, Context, Poll}; /// use tokio_util::io::{StreamReader, poll_read_buf}; /// use std::future::poll_fn; /// use std::pin::Pin; -/// # #[tokio::main] +/// # #[tokio::main(flavor = "current_thread")] /// # async fn main() -> std::io::Result<()> { /// /// // Create a reader from an iterator. This particular reader will always be diff --git a/tokio/src/io/mod.rs b/tokio/src/io/mod.rs index 8b20ea6b..01316854 100644 --- a/tokio/src/io/mod.rs +++ b/tokio/src/io/mod.rs @@ -36,6 +36,8 @@ //! 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; //! @@ -50,6 +52,7 @@ //! println!("The bytes: {:?}", &buffer[..n]); //! Ok(()) //! } +//! # } //! ``` //! //! [`File`]: crate::fs::File @@ -73,6 +76,8 @@ //! extra methods to any async reader: //! //! ```no_run +//! # #[cfg(not(target_family = "wasm"))] +//! # { //! use tokio::io::{self, BufReader, AsyncBufReadExt}; //! use tokio::fs::File; //! @@ -88,6 +93,7 @@ //! println!("{}", buffer); //! Ok(()) //! } +//! # } //! ``` //! //! [`BufWriter`] doesn't add any new ways of writing; it just buffers every call @@ -95,6 +101,8 @@ //! [`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; //! @@ -114,6 +122,7 @@ //! //! Ok(()) //! } +//! # } //! ``` //! //! [stdbuf]: std::io#bufreader-and-bufwriter diff --git a/tokio/src/io/util/async_buf_read_ext.rs b/tokio/src/io/util/async_buf_read_ext.rs index 1e9da4c8..f6ef7419 100644 --- a/tokio/src/io/util/async_buf_read_ext.rs +++ b/tokio/src/io/util/async_buf_read_ext.rs @@ -62,36 +62,36 @@ cfg_io_util! { /// /// use std::io::Cursor; /// - /// #[tokio::main] - /// async fn main() { - /// let mut cursor = Cursor::new(b"lorem-ipsum"); - /// let mut buf = vec![]; - /// - /// // cursor is at 'l' - /// let num_bytes = cursor.read_until(b'-', &mut buf) - /// .await - /// .expect("reading from cursor won't fail"); - /// - /// assert_eq!(num_bytes, 6); - /// assert_eq!(buf, b"lorem-"); - /// buf.clear(); - /// - /// // cursor is at 'i' - /// let num_bytes = cursor.read_until(b'-', &mut buf) - /// .await - /// .expect("reading from cursor won't fail"); - /// - /// assert_eq!(num_bytes, 5); - /// assert_eq!(buf, b"ipsum"); - /// buf.clear(); - /// - /// // cursor is at EOF - /// let num_bytes = cursor.read_until(b'-', &mut buf) - /// .await - /// .expect("reading from cursor won't fail"); - /// assert_eq!(num_bytes, 0); - /// assert_eq!(buf, b""); - /// } + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let mut cursor = Cursor::new(b"lorem-ipsum"); + /// let mut buf = vec![]; + /// + /// // cursor is at 'l' + /// let num_bytes = cursor.read_until(b'-', &mut buf) + /// .await + /// .expect("reading from cursor won't fail"); + /// + /// assert_eq!(num_bytes, 6); + /// assert_eq!(buf, b"lorem-"); + /// buf.clear(); + /// + /// // cursor is at 'i' + /// let num_bytes = cursor.read_until(b'-', &mut buf) + /// .await + /// .expect("reading from cursor won't fail"); + /// + /// assert_eq!(num_bytes, 5); + /// assert_eq!(buf, b"ipsum"); + /// buf.clear(); + /// + /// // cursor is at EOF + /// let num_bytes = cursor.read_until(b'-', &mut buf) + /// .await + /// .expect("reading from cursor won't fail"); + /// assert_eq!(num_bytes, 0); + /// assert_eq!(buf, b""); + /// # } /// ``` fn read_until<'a>(&'a mut self, byte: u8, buf: &'a mut Vec) -> ReadUntil<'a, Self> where @@ -164,37 +164,37 @@ cfg_io_util! { /// /// use std::io::Cursor; /// - /// #[tokio::main] - /// async fn main() { - /// let mut cursor = Cursor::new(b"foo\nbar"); - /// let mut buf = String::new(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let mut cursor = Cursor::new(b"foo\nbar"); + /// let mut buf = String::new(); /// - /// // cursor is at 'f' - /// let num_bytes = cursor.read_line(&mut buf) - /// .await - /// .expect("reading from cursor won't fail"); + /// // cursor is at 'f' + /// let num_bytes = cursor.read_line(&mut buf) + /// .await + /// .expect("reading from cursor won't fail"); /// - /// assert_eq!(num_bytes, 4); - /// assert_eq!(buf, "foo\n"); - /// buf.clear(); + /// assert_eq!(num_bytes, 4); + /// assert_eq!(buf, "foo\n"); + /// buf.clear(); /// - /// // cursor is at 'b' - /// let num_bytes = cursor.read_line(&mut buf) - /// .await - /// .expect("reading from cursor won't fail"); + /// // cursor is at 'b' + /// let num_bytes = cursor.read_line(&mut buf) + /// .await + /// .expect("reading from cursor won't fail"); /// - /// assert_eq!(num_bytes, 3); - /// assert_eq!(buf, "bar"); - /// buf.clear(); + /// assert_eq!(num_bytes, 3); + /// assert_eq!(buf, "bar"); + /// buf.clear(); /// - /// // cursor is at EOF - /// let num_bytes = cursor.read_line(&mut buf) - /// .await - /// .expect("reading from cursor won't fail"); + /// // cursor is at EOF + /// let num_bytes = cursor.read_line(&mut buf) + /// .await + /// .expect("reading from cursor won't fail"); /// - /// assert_eq!(num_bytes, 0); - /// assert_eq!(buf, ""); - /// } + /// assert_eq!(num_bytes, 0); + /// assert_eq!(buf, ""); + /// # } /// ``` fn read_line<'a>(&'a mut self, buf: &'a mut String) -> ReadLine<'a, Self> where @@ -331,17 +331,17 @@ cfg_io_util! { /// /// use std::io::Cursor; /// - /// #[tokio::main] - /// async fn main() { - /// let cursor = Cursor::new(b"lorem\nipsum\r\ndolor"); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let cursor = Cursor::new(b"lorem\nipsum\r\ndolor"); /// - /// let mut lines = cursor.lines(); + /// let mut lines = cursor.lines(); /// - /// assert_eq!(lines.next_line().await.unwrap(), Some(String::from("lorem"))); - /// assert_eq!(lines.next_line().await.unwrap(), Some(String::from("ipsum"))); - /// assert_eq!(lines.next_line().await.unwrap(), Some(String::from("dolor"))); - /// assert_eq!(lines.next_line().await.unwrap(), None); - /// } + /// assert_eq!(lines.next_line().await.unwrap(), Some(String::from("lorem"))); + /// assert_eq!(lines.next_line().await.unwrap(), Some(String::from("ipsum"))); + /// assert_eq!(lines.next_line().await.unwrap(), Some(String::from("dolor"))); + /// assert_eq!(lines.next_line().await.unwrap(), None); + /// # } /// ``` /// /// [`AsyncBufReadExt::read_line`]: AsyncBufReadExt::read_line diff --git a/tokio/src/io/util/async_read_ext.rs b/tokio/src/io/util/async_read_ext.rs index 8c803851..59de6cdb 100644 --- a/tokio/src/io/util/async_read_ext.rs +++ b/tokio/src/io/util/async_read_ext.rs @@ -41,6 +41,8 @@ cfg_io_util! { /// [`AsyncRead`]. /// /// ```no_run + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::fs::File; /// use tokio::io::{self, AsyncReadExt}; /// @@ -54,6 +56,7 @@ cfg_io_util! { /// /// Ok(()) /// } + /// # } /// ``` /// /// See [module][crate::io] documentation for more details. @@ -72,6 +75,8 @@ cfg_io_util! { /// [`File`][crate::fs::File]s implement `AsyncRead`: /// /// ```no_run + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::fs::File; /// use tokio::io::{self, AsyncReadExt}; /// @@ -88,6 +93,7 @@ cfg_io_util! { /// handle.read_to_string(&mut buffer).await?; /// Ok(()) /// } + /// # } /// ``` fn chain(self, next: R) -> Chain where @@ -150,6 +156,8 @@ cfg_io_util! { /// [`File`][crate::fs::File]s implement `Read`: /// /// ```no_run + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::fs::File; /// use tokio::io::{self, AsyncReadExt}; /// @@ -164,6 +172,7 @@ cfg_io_util! { /// println!("The bytes: {:?}", &buffer[..n]); /// Ok(()) /// } + /// # } /// ``` fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Read<'a, Self> where @@ -219,6 +228,8 @@ cfg_io_util! { /// [`BufMut`]: bytes::BufMut /// /// ```no_run + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::fs::File; /// use tokio::io::{self, AsyncReadExt}; /// @@ -242,6 +253,7 @@ cfg_io_util! { /// println!("The bytes: {:?}", &buffer[..]); /// Ok(()) /// } + /// # } /// ``` fn read_buf<'a, B>(&'a mut self, buf: &'a mut B) -> ReadBuf<'a, Self, B> where @@ -289,6 +301,8 @@ cfg_io_util! { /// [`File`][crate::fs::File]s implement `Read`: /// /// ```no_run + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::fs::File; /// use tokio::io::{self, AsyncReadExt}; /// @@ -302,6 +316,7 @@ cfg_io_util! { /// f.read_exact(&mut buffer).await?; /// Ok(()) /// } + /// # } /// ``` /// /// [`ErrorKind::UnexpectedEof`]: std::io::ErrorKind::UnexpectedEof @@ -345,15 +360,15 @@ cfg_io_util! { /// /// use std::io::Cursor; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut reader = Cursor::new(vec![2, 5]); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut reader = Cursor::new(vec![2, 5]); /// - /// assert_eq!(2, reader.read_u8().await?); - /// assert_eq!(5, reader.read_u8().await?); + /// assert_eq!(2, reader.read_u8().await?); + /// assert_eq!(5, reader.read_u8().await?); /// - /// Ok(()) - /// } + /// Ok(()) + /// # } /// ``` fn read_u8(&mut self) -> ReadU8; @@ -389,15 +404,15 @@ cfg_io_util! { /// /// use std::io::Cursor; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut reader = Cursor::new(vec![0x02, 0xfb]); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut reader = Cursor::new(vec![0x02, 0xfb]); /// - /// assert_eq!(2, reader.read_i8().await?); - /// assert_eq!(-5, reader.read_i8().await?); + /// assert_eq!(2, reader.read_i8().await?); + /// assert_eq!(-5, reader.read_i8().await?); /// - /// Ok(()) - /// } + /// Ok(()) + /// # } /// ``` fn read_i8(&mut self) -> ReadI8; @@ -434,14 +449,14 @@ cfg_io_util! { /// /// use std::io::Cursor; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut reader = Cursor::new(vec![2, 5, 3, 0]); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut reader = Cursor::new(vec![2, 5, 3, 0]); /// - /// assert_eq!(517, reader.read_u16().await?); - /// assert_eq!(768, reader.read_u16().await?); - /// Ok(()) - /// } + /// assert_eq!(517, reader.read_u16().await?); + /// assert_eq!(768, reader.read_u16().await?); + /// Ok(()) + /// # } /// ``` fn read_u16(&mut self) -> ReadU16; @@ -478,14 +493,14 @@ cfg_io_util! { /// /// use std::io::Cursor; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut reader = Cursor::new(vec![0x00, 0xc1, 0xff, 0x7c]); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut reader = Cursor::new(vec![0x00, 0xc1, 0xff, 0x7c]); /// - /// assert_eq!(193, reader.read_i16().await?); - /// assert_eq!(-132, reader.read_i16().await?); - /// Ok(()) - /// } + /// assert_eq!(193, reader.read_i16().await?); + /// assert_eq!(-132, reader.read_i16().await?); + /// Ok(()) + /// # } /// ``` fn read_i16(&mut self) -> ReadI16; @@ -522,13 +537,13 @@ cfg_io_util! { /// /// use std::io::Cursor; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut reader = Cursor::new(vec![0x00, 0x00, 0x01, 0x0b]); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut reader = Cursor::new(vec![0x00, 0x00, 0x01, 0x0b]); /// - /// assert_eq!(267, reader.read_u32().await?); - /// Ok(()) - /// } + /// assert_eq!(267, reader.read_u32().await?); + /// Ok(()) + /// # } /// ``` fn read_u32(&mut self) -> ReadU32; @@ -566,13 +581,13 @@ cfg_io_util! { /// /// use std::io::Cursor; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut reader = Cursor::new(vec![0xff, 0xff, 0x7a, 0x33]); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut reader = Cursor::new(vec![0xff, 0xff, 0x7a, 0x33]); /// - /// assert_eq!(-34253, reader.read_i32().await?); - /// Ok(()) - /// } + /// assert_eq!(-34253, reader.read_i32().await?); + /// Ok(()) + /// # } /// ``` fn read_i32(&mut self) -> ReadI32; @@ -609,15 +624,15 @@ cfg_io_util! { /// /// use std::io::Cursor; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut reader = Cursor::new(vec![ - /// 0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83 - /// ]); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut reader = Cursor::new(vec![ + /// 0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83 + /// ]); /// - /// assert_eq!(918733457491587, reader.read_u64().await?); - /// Ok(()) - /// } + /// assert_eq!(918733457491587, reader.read_u64().await?); + /// Ok(()) + /// # } /// ``` fn read_u64(&mut self) -> ReadU64; @@ -654,13 +669,13 @@ cfg_io_util! { /// /// use std::io::Cursor; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut reader = Cursor::new(vec![0x80, 0, 0, 0, 0, 0, 0, 0]); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut reader = Cursor::new(vec![0x80, 0, 0, 0, 0, 0, 0, 0]); /// - /// assert_eq!(i64::MIN, reader.read_i64().await?); - /// Ok(()) - /// } + /// assert_eq!(i64::MIN, reader.read_i64().await?); + /// Ok(()) + /// # } /// ``` fn read_i64(&mut self) -> ReadI64; @@ -697,16 +712,16 @@ cfg_io_util! { /// /// use std::io::Cursor; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut reader = Cursor::new(vec![ + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut reader = Cursor::new(vec![ /// 0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83, - /// 0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83 - /// ]); + /// 0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83 + /// ]); /// - /// assert_eq!(16947640962301618749969007319746179, reader.read_u128().await?); - /// Ok(()) - /// } + /// assert_eq!(16947640962301618749969007319746179, reader.read_u128().await?); + /// Ok(()) + /// # } /// ``` fn read_u128(&mut self) -> ReadU128; @@ -743,16 +758,16 @@ cfg_io_util! { /// /// use std::io::Cursor; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut reader = Cursor::new(vec![ - /// 0x80, 0, 0, 0, 0, 0, 0, 0, - /// 0, 0, 0, 0, 0, 0, 0, 0 - /// ]); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut reader = Cursor::new(vec![ + /// 0x80, 0, 0, 0, 0, 0, 0, 0, + /// 0, 0, 0, 0, 0, 0, 0, 0 + /// ]); /// - /// assert_eq!(i128::MIN, reader.read_i128().await?); - /// Ok(()) - /// } + /// assert_eq!(i128::MIN, reader.read_i128().await?); + /// Ok(()) + /// # } /// ``` fn read_i128(&mut self) -> ReadI128; @@ -789,13 +804,13 @@ cfg_io_util! { /// /// use std::io::Cursor; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut reader = Cursor::new(vec![0xff, 0x7f, 0xff, 0xff]); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut reader = Cursor::new(vec![0xff, 0x7f, 0xff, 0xff]); /// - /// assert_eq!(f32::MIN, reader.read_f32().await?); - /// Ok(()) - /// } + /// assert_eq!(f32::MIN, reader.read_f32().await?); + /// Ok(()) + /// # } /// ``` fn read_f32(&mut self) -> ReadF32; @@ -832,15 +847,15 @@ cfg_io_util! { /// /// use std::io::Cursor; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut reader = Cursor::new(vec![ - /// 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff - /// ]); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut reader = Cursor::new(vec![ + /// 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + /// ]); /// - /// assert_eq!(f64::MIN, reader.read_f64().await?); - /// Ok(()) - /// } + /// assert_eq!(f64::MIN, reader.read_f64().await?); + /// Ok(()) + /// # } /// ``` fn read_f64(&mut self) -> ReadF64; @@ -877,14 +892,14 @@ cfg_io_util! { /// /// use std::io::Cursor; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut reader = Cursor::new(vec![2, 5, 3, 0]); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut reader = Cursor::new(vec![2, 5, 3, 0]); /// - /// assert_eq!(1282, reader.read_u16_le().await?); - /// assert_eq!(3, reader.read_u16_le().await?); - /// Ok(()) - /// } + /// assert_eq!(1282, reader.read_u16_le().await?); + /// assert_eq!(3, reader.read_u16_le().await?); + /// Ok(()) + /// # } /// ``` fn read_u16_le(&mut self) -> ReadU16Le; @@ -921,14 +936,14 @@ cfg_io_util! { /// /// use std::io::Cursor; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut reader = Cursor::new(vec![0x00, 0xc1, 0xff, 0x7c]); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut reader = Cursor::new(vec![0x00, 0xc1, 0xff, 0x7c]); /// - /// assert_eq!(-16128, reader.read_i16_le().await?); - /// assert_eq!(31999, reader.read_i16_le().await?); - /// Ok(()) - /// } + /// assert_eq!(-16128, reader.read_i16_le().await?); + /// assert_eq!(31999, reader.read_i16_le().await?); + /// Ok(()) + /// # } /// ``` fn read_i16_le(&mut self) -> ReadI16Le; @@ -965,13 +980,13 @@ cfg_io_util! { /// /// use std::io::Cursor; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut reader = Cursor::new(vec![0x00, 0x00, 0x01, 0x0b]); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut reader = Cursor::new(vec![0x00, 0x00, 0x01, 0x0b]); /// - /// assert_eq!(184614912, reader.read_u32_le().await?); - /// Ok(()) - /// } + /// assert_eq!(184614912, reader.read_u32_le().await?); + /// Ok(()) + /// # } /// ``` fn read_u32_le(&mut self) -> ReadU32Le; @@ -1009,13 +1024,13 @@ cfg_io_util! { /// /// use std::io::Cursor; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut reader = Cursor::new(vec![0xff, 0xff, 0x7a, 0x33]); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut reader = Cursor::new(vec![0xff, 0xff, 0x7a, 0x33]); /// - /// assert_eq!(863698943, reader.read_i32_le().await?); - /// Ok(()) - /// } + /// assert_eq!(863698943, reader.read_i32_le().await?); + /// Ok(()) + /// # } /// ``` fn read_i32_le(&mut self) -> ReadI32Le; @@ -1052,15 +1067,15 @@ cfg_io_util! { /// /// use std::io::Cursor; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut reader = Cursor::new(vec![ - /// 0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83 - /// ]); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut reader = Cursor::new(vec![ + /// 0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83 + /// ]); /// - /// assert_eq!(9477368352180732672, reader.read_u64_le().await?); - /// Ok(()) - /// } + /// assert_eq!(9477368352180732672, reader.read_u64_le().await?); + /// Ok(()) + /// # } /// ``` fn read_u64_le(&mut self) -> ReadU64Le; @@ -1097,13 +1112,13 @@ cfg_io_util! { /// /// use std::io::Cursor; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut reader = Cursor::new(vec![0x80, 0, 0, 0, 0, 0, 0, 0]); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut reader = Cursor::new(vec![0x80, 0, 0, 0, 0, 0, 0, 0]); /// - /// assert_eq!(128, reader.read_i64_le().await?); - /// Ok(()) - /// } + /// assert_eq!(128, reader.read_i64_le().await?); + /// Ok(()) + /// # } /// ``` fn read_i64_le(&mut self) -> ReadI64Le; @@ -1140,16 +1155,16 @@ cfg_io_util! { /// /// use std::io::Cursor; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut reader = Cursor::new(vec![ - /// 0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83, - /// 0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83 - /// ]); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut reader = Cursor::new(vec![ + /// 0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83, + /// 0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83 + /// ]); /// - /// assert_eq!(174826588484952389081207917399662330624, reader.read_u128_le().await?); - /// Ok(()) - /// } + /// assert_eq!(174826588484952389081207917399662330624, reader.read_u128_le().await?); + /// Ok(()) + /// # } /// ``` fn read_u128_le(&mut self) -> ReadU128Le; @@ -1186,16 +1201,16 @@ cfg_io_util! { /// /// use std::io::Cursor; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut reader = Cursor::new(vec![ - /// 0x80, 0, 0, 0, 0, 0, 0, 0, - /// 0, 0, 0, 0, 0, 0, 0, 0 - /// ]); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut reader = Cursor::new(vec![ + /// 0x80, 0, 0, 0, 0, 0, 0, 0, + /// 0, 0, 0, 0, 0, 0, 0, 0 + /// ]); /// - /// assert_eq!(128, reader.read_i128_le().await?); - /// Ok(()) - /// } + /// assert_eq!(128, reader.read_i128_le().await?); + /// Ok(()) + /// # } /// ``` fn read_i128_le(&mut self) -> ReadI128Le; @@ -1232,13 +1247,13 @@ cfg_io_util! { /// /// use std::io::Cursor; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut reader = Cursor::new(vec![0xff, 0xff, 0x7f, 0xff]); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut reader = Cursor::new(vec![0xff, 0xff, 0x7f, 0xff]); /// - /// assert_eq!(f32::MIN, reader.read_f32_le().await?); - /// Ok(()) - /// } + /// assert_eq!(f32::MIN, reader.read_f32_le().await?); + /// Ok(()) + /// # } /// ``` fn read_f32_le(&mut self) -> ReadF32Le; @@ -1275,15 +1290,15 @@ cfg_io_util! { /// /// use std::io::Cursor; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut reader = Cursor::new(vec![ - /// 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff - /// ]); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut reader = Cursor::new(vec![ + /// 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff + /// ]); /// - /// assert_eq!(f64::MIN, reader.read_f64_le().await?); - /// Ok(()) - /// } + /// assert_eq!(f64::MIN, reader.read_f64_le().await?); + /// Ok(()) + /// # } /// ``` fn read_f64_le(&mut self) -> ReadF64Le; } @@ -1315,6 +1330,8 @@ cfg_io_util! { /// [`File`][crate::fs::File]s implement `Read`: /// /// ```no_run + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::io::{self, AsyncReadExt}; /// use tokio::fs::File; /// @@ -1327,6 +1344,7 @@ cfg_io_util! { /// f.read_to_end(&mut buffer).await?; /// Ok(()) /// } + /// # } /// ``` /// /// (See also the [`tokio::fs::read`] convenience function for reading from a @@ -1363,6 +1381,8 @@ cfg_io_util! { /// [`File`][crate::fs::File]s implement `Read`: /// /// ```no_run + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::io::{self, AsyncReadExt}; /// use tokio::fs::File; /// @@ -1374,6 +1394,7 @@ cfg_io_util! { /// f.read_to_string(&mut buffer).await?; /// Ok(()) /// } + /// # } /// ``` /// /// (See also the [`crate::fs::read_to_string`] convenience function for @@ -1403,6 +1424,8 @@ cfg_io_util! { /// [`File`][crate::fs::File]s implement `Read`: /// /// ```no_run + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::io::{self, AsyncReadExt}; /// use tokio::fs::File; /// @@ -1417,6 +1440,7 @@ cfg_io_util! { /// handle.read(&mut buffer).await?; /// Ok(()) /// } + /// # } /// ``` fn take(self, limit: u64) -> Take where diff --git a/tokio/src/io/util/async_seek_ext.rs b/tokio/src/io/util/async_seek_ext.rs index aadf3a76..c4513930 100644 --- a/tokio/src/io/util/async_seek_ext.rs +++ b/tokio/src/io/util/async_seek_ext.rs @@ -11,20 +11,20 @@ cfg_io_util! { /// use std::io::{self, Cursor, SeekFrom}; /// use tokio::io::{AsyncSeekExt, AsyncReadExt}; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut cursor = Cursor::new(b"abcdefg"); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut cursor = Cursor::new(b"abcdefg"); /// - /// // the `seek` method is defined by this trait - /// cursor.seek(SeekFrom::Start(3)).await?; + /// // the `seek` method is defined by this trait + /// cursor.seek(SeekFrom::Start(3)).await?; /// - /// let mut buf = [0; 1]; - /// let n = cursor.read(&mut buf).await?; - /// assert_eq!(n, 1); - /// assert_eq!(buf, [b'd']); + /// let mut buf = [0; 1]; + /// let n = cursor.read(&mut buf).await?; + /// assert_eq!(n, 1); + /// assert_eq!(buf, [b'd']); /// - /// Ok(()) - /// } + /// Ok(()) + /// # } /// ``` /// /// See [module][crate::io] documentation for more details. @@ -46,6 +46,8 @@ cfg_io_util! { /// # Examples /// /// ```no_run + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::fs::File; /// use tokio::io::{AsyncSeekExt, AsyncReadExt}; /// @@ -59,6 +61,7 @@ cfg_io_util! { /// file.read_exact(&mut contents).await?; /// # Ok(()) /// # } + /// # } /// ``` fn seek(&mut self, pos: SeekFrom) -> Seek<'_, Self> where diff --git a/tokio/src/io/util/async_write_ext.rs b/tokio/src/io/util/async_write_ext.rs index cd42d4f0..db4400bb 100644 --- a/tokio/src/io/util/async_write_ext.rs +++ b/tokio/src/io/util/async_write_ext.rs @@ -44,6 +44,8 @@ cfg_io_util! { /// [`AsyncWrite`]. /// /// ```no_run + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::io::{self, AsyncWriteExt}; /// use tokio::fs::File; /// @@ -61,6 +63,7 @@ cfg_io_util! { /// /// Ok(()) /// } + /// # } /// ``` /// /// See [module][crate::io] documentation for more details. @@ -108,6 +111,8 @@ cfg_io_util! { /// # Examples /// /// ```no_run + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::io::{self, AsyncWriteExt}; /// use tokio::fs::File; /// @@ -120,6 +125,7 @@ cfg_io_util! { /// file.flush().await?; /// Ok(()) /// } + /// # } /// ``` fn write<'a>(&'a mut self, src: &'a [u8]) -> Write<'a, Self> where @@ -148,6 +154,8 @@ cfg_io_util! { /// # Examples /// /// ```no_run + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::io::{self, AsyncWriteExt}; /// use tokio::fs::File; /// use std::io::IoSlice; @@ -167,6 +175,7 @@ cfg_io_util! { /// /// Ok(()) /// } + /// # } /// ``` /// /// [`write`]: AsyncWriteExt::write @@ -228,6 +237,8 @@ cfg_io_util! { /// [`Cursor`]: std::io::Cursor /// /// ```no_run + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::io::{self, AsyncWriteExt}; /// use tokio::fs::File; /// @@ -250,6 +261,7 @@ cfg_io_util! { /// /// Ok(()) /// } + /// # } /// ``` fn write_buf<'a, B>(&'a mut self, src: &'a mut B) -> WriteBuf<'a, Self, B> where @@ -299,6 +311,8 @@ cfg_io_util! { /// [advanced]: bytes::Buf::advance /// /// ```no_run + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::io::{self, AsyncWriteExt}; /// use tokio::fs::File; /// @@ -313,6 +327,7 @@ cfg_io_util! { /// file.flush().await?; /// Ok(()) /// } + /// # } /// ``` /// /// [`write`]: AsyncWriteExt::write @@ -352,6 +367,8 @@ cfg_io_util! { /// # Examples /// /// ```no_run + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::io::{self, AsyncWriteExt}; /// use tokio::fs::File; /// @@ -363,6 +380,7 @@ cfg_io_util! { /// file.flush().await?; /// Ok(()) /// } + /// # } /// ``` /// /// [`write`]: AsyncWriteExt::write @@ -398,16 +416,16 @@ cfg_io_util! { /// ```rust /// use tokio::io::{self, AsyncWriteExt}; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut writer = Vec::new(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut writer = Vec::new(); /// - /// writer.write_u8(2).await?; - /// writer.write_u8(5).await?; + /// writer.write_u8(2).await?; + /// writer.write_u8(5).await?; /// - /// assert_eq!(writer, b"\x02\x05"); - /// Ok(()) - /// } + /// assert_eq!(writer, b"\x02\x05"); + /// Ok(()) + /// # } /// ``` fn write_u8(&mut self, n: u8) -> WriteU8; @@ -435,16 +453,16 @@ cfg_io_util! { /// ```rust /// use tokio::io::{self, AsyncWriteExt}; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut writer = Vec::new(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut writer = Vec::new(); /// - /// writer.write_i8(-2).await?; - /// writer.write_i8(126).await?; + /// writer.write_i8(-2).await?; + /// writer.write_i8(126).await?; /// - /// assert_eq!(writer, b"\xFE\x7E"); - /// Ok(()) - /// } + /// assert_eq!(writer, b"\xFE\x7E"); + /// Ok(()) + /// # } /// ``` fn write_i8(&mut self, n: i8) -> WriteI8; @@ -473,16 +491,16 @@ cfg_io_util! { /// ```rust /// use tokio::io::{self, AsyncWriteExt}; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut writer = Vec::new(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut writer = Vec::new(); /// - /// writer.write_u16(517).await?; - /// writer.write_u16(768).await?; + /// writer.write_u16(517).await?; + /// writer.write_u16(768).await?; /// - /// assert_eq!(writer, b"\x02\x05\x03\x00"); - /// Ok(()) - /// } + /// assert_eq!(writer, b"\x02\x05\x03\x00"); + /// Ok(()) + /// # } /// ``` fn write_u16(&mut self, n: u16) -> WriteU16; @@ -511,16 +529,16 @@ cfg_io_util! { /// ```rust /// use tokio::io::{self, AsyncWriteExt}; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut writer = Vec::new(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut writer = Vec::new(); /// - /// writer.write_i16(193).await?; - /// writer.write_i16(-132).await?; + /// writer.write_i16(193).await?; + /// writer.write_i16(-132).await?; /// - /// assert_eq!(writer, b"\x00\xc1\xff\x7c"); - /// Ok(()) - /// } + /// assert_eq!(writer, b"\x00\xc1\xff\x7c"); + /// Ok(()) + /// # } /// ``` fn write_i16(&mut self, n: i16) -> WriteI16; @@ -549,16 +567,16 @@ cfg_io_util! { /// ```rust /// use tokio::io::{self, AsyncWriteExt}; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut writer = Vec::new(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut writer = Vec::new(); /// - /// writer.write_u32(267).await?; - /// writer.write_u32(1205419366).await?; + /// writer.write_u32(267).await?; + /// writer.write_u32(1205419366).await?; /// - /// assert_eq!(writer, b"\x00\x00\x01\x0b\x47\xd9\x3d\x66"); - /// Ok(()) - /// } + /// assert_eq!(writer, b"\x00\x00\x01\x0b\x47\xd9\x3d\x66"); + /// Ok(()) + /// # } /// ``` fn write_u32(&mut self, n: u32) -> WriteU32; @@ -587,16 +605,16 @@ cfg_io_util! { /// ```rust /// use tokio::io::{self, AsyncWriteExt}; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut writer = Vec::new(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut writer = Vec::new(); /// - /// writer.write_i32(267).await?; - /// writer.write_i32(1205419366).await?; + /// writer.write_i32(267).await?; + /// writer.write_i32(1205419366).await?; /// - /// assert_eq!(writer, b"\x00\x00\x01\x0b\x47\xd9\x3d\x66"); - /// Ok(()) - /// } + /// assert_eq!(writer, b"\x00\x00\x01\x0b\x47\xd9\x3d\x66"); + /// Ok(()) + /// # } /// ``` fn write_i32(&mut self, n: i32) -> WriteI32; @@ -625,16 +643,16 @@ cfg_io_util! { /// ```rust /// use tokio::io::{self, AsyncWriteExt}; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut writer = Vec::new(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut writer = Vec::new(); /// - /// writer.write_u64(918733457491587).await?; - /// writer.write_u64(143).await?; + /// writer.write_u64(918733457491587).await?; + /// writer.write_u64(143).await?; /// - /// assert_eq!(writer, b"\x00\x03\x43\x95\x4d\x60\x86\x83\x00\x00\x00\x00\x00\x00\x00\x8f"); - /// Ok(()) - /// } + /// assert_eq!(writer, b"\x00\x03\x43\x95\x4d\x60\x86\x83\x00\x00\x00\x00\x00\x00\x00\x8f"); + /// Ok(()) + /// # } /// ``` fn write_u64(&mut self, n: u64) -> WriteU64; @@ -663,16 +681,16 @@ cfg_io_util! { /// ```rust /// use tokio::io::{self, AsyncWriteExt}; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut writer = Vec::new(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut writer = Vec::new(); /// - /// writer.write_i64(i64::MIN).await?; - /// writer.write_i64(i64::MAX).await?; + /// writer.write_i64(i64::MIN).await?; + /// writer.write_i64(i64::MAX).await?; /// - /// assert_eq!(writer, b"\x80\x00\x00\x00\x00\x00\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff"); - /// Ok(()) - /// } + /// assert_eq!(writer, b"\x80\x00\x00\x00\x00\x00\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff"); + /// Ok(()) + /// # } /// ``` fn write_i64(&mut self, n: i64) -> WriteI64; @@ -701,18 +719,18 @@ cfg_io_util! { /// ```rust /// use tokio::io::{self, AsyncWriteExt}; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut writer = Vec::new(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut writer = Vec::new(); /// - /// writer.write_u128(16947640962301618749969007319746179).await?; + /// writer.write_u128(16947640962301618749969007319746179).await?; /// - /// assert_eq!(writer, vec![ - /// 0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83, - /// 0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83 - /// ]); - /// Ok(()) - /// } + /// assert_eq!(writer, vec![ + /// 0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83, + /// 0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83 + /// ]); + /// Ok(()) + /// # } /// ``` fn write_u128(&mut self, n: u128) -> WriteU128; @@ -741,18 +759,18 @@ cfg_io_util! { /// ```rust /// use tokio::io::{self, AsyncWriteExt}; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut writer = Vec::new(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut writer = Vec::new(); /// - /// writer.write_i128(i128::MIN).await?; + /// writer.write_i128(i128::MIN).await?; /// - /// assert_eq!(writer, vec![ - /// 0x80, 0, 0, 0, 0, 0, 0, 0, - /// 0, 0, 0, 0, 0, 0, 0, 0 - /// ]); - /// Ok(()) - /// } + /// assert_eq!(writer, vec![ + /// 0x80, 0, 0, 0, 0, 0, 0, 0, + /// 0, 0, 0, 0, 0, 0, 0, 0 + /// ]); + /// Ok(()) + /// # } /// ``` fn write_i128(&mut self, n: i128) -> WriteI128; @@ -781,15 +799,15 @@ cfg_io_util! { /// ```rust /// use tokio::io::{self, AsyncWriteExt}; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut writer = Vec::new(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut writer = Vec::new(); /// - /// writer.write_f32(f32::MIN).await?; + /// writer.write_f32(f32::MIN).await?; /// - /// assert_eq!(writer, vec![0xff, 0x7f, 0xff, 0xff]); - /// Ok(()) - /// } + /// assert_eq!(writer, vec![0xff, 0x7f, 0xff, 0xff]); + /// Ok(()) + /// # } /// ``` fn write_f32(&mut self, n: f32) -> WriteF32; @@ -818,17 +836,17 @@ cfg_io_util! { /// ```rust /// use tokio::io::{self, AsyncWriteExt}; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut writer = Vec::new(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut writer = Vec::new(); /// - /// writer.write_f64(f64::MIN).await?; + /// writer.write_f64(f64::MIN).await?; /// - /// assert_eq!(writer, vec![ - /// 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff - /// ]); - /// Ok(()) - /// } + /// assert_eq!(writer, vec![ + /// 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + /// ]); + /// Ok(()) + /// # } /// ``` fn write_f64(&mut self, n: f64) -> WriteF64; @@ -857,16 +875,16 @@ cfg_io_util! { /// ```rust /// use tokio::io::{self, AsyncWriteExt}; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut writer = Vec::new(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut writer = Vec::new(); /// - /// writer.write_u16_le(517).await?; - /// writer.write_u16_le(768).await?; + /// writer.write_u16_le(517).await?; + /// writer.write_u16_le(768).await?; /// - /// assert_eq!(writer, b"\x05\x02\x00\x03"); - /// Ok(()) - /// } + /// assert_eq!(writer, b"\x05\x02\x00\x03"); + /// Ok(()) + /// # } /// ``` fn write_u16_le(&mut self, n: u16) -> WriteU16Le; @@ -895,16 +913,16 @@ cfg_io_util! { /// ```rust /// use tokio::io::{self, AsyncWriteExt}; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut writer = Vec::new(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut writer = Vec::new(); /// - /// writer.write_i16_le(193).await?; - /// writer.write_i16_le(-132).await?; + /// writer.write_i16_le(193).await?; + /// writer.write_i16_le(-132).await?; /// - /// assert_eq!(writer, b"\xc1\x00\x7c\xff"); - /// Ok(()) - /// } + /// assert_eq!(writer, b"\xc1\x00\x7c\xff"); + /// Ok(()) + /// # } /// ``` fn write_i16_le(&mut self, n: i16) -> WriteI16Le; @@ -933,16 +951,16 @@ cfg_io_util! { /// ```rust /// use tokio::io::{self, AsyncWriteExt}; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut writer = Vec::new(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut writer = Vec::new(); /// - /// writer.write_u32_le(267).await?; - /// writer.write_u32_le(1205419366).await?; + /// writer.write_u32_le(267).await?; + /// writer.write_u32_le(1205419366).await?; /// - /// assert_eq!(writer, b"\x0b\x01\x00\x00\x66\x3d\xd9\x47"); - /// Ok(()) - /// } + /// assert_eq!(writer, b"\x0b\x01\x00\x00\x66\x3d\xd9\x47"); + /// Ok(()) + /// # } /// ``` fn write_u32_le(&mut self, n: u32) -> WriteU32Le; @@ -971,16 +989,16 @@ cfg_io_util! { /// ```rust /// use tokio::io::{self, AsyncWriteExt}; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut writer = Vec::new(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut writer = Vec::new(); /// - /// writer.write_i32_le(267).await?; - /// writer.write_i32_le(1205419366).await?; + /// writer.write_i32_le(267).await?; + /// writer.write_i32_le(1205419366).await?; /// - /// assert_eq!(writer, b"\x0b\x01\x00\x00\x66\x3d\xd9\x47"); - /// Ok(()) - /// } + /// assert_eq!(writer, b"\x0b\x01\x00\x00\x66\x3d\xd9\x47"); + /// Ok(()) + /// # } /// ``` fn write_i32_le(&mut self, n: i32) -> WriteI32Le; @@ -1009,16 +1027,16 @@ cfg_io_util! { /// ```rust /// use tokio::io::{self, AsyncWriteExt}; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut writer = Vec::new(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut writer = Vec::new(); /// - /// writer.write_u64_le(918733457491587).await?; - /// writer.write_u64_le(143).await?; + /// writer.write_u64_le(918733457491587).await?; + /// writer.write_u64_le(143).await?; /// - /// assert_eq!(writer, b"\x83\x86\x60\x4d\x95\x43\x03\x00\x8f\x00\x00\x00\x00\x00\x00\x00"); - /// Ok(()) - /// } + /// assert_eq!(writer, b"\x83\x86\x60\x4d\x95\x43\x03\x00\x8f\x00\x00\x00\x00\x00\x00\x00"); + /// Ok(()) + /// # } /// ``` fn write_u64_le(&mut self, n: u64) -> WriteU64Le; @@ -1047,16 +1065,16 @@ cfg_io_util! { /// ```rust /// use tokio::io::{self, AsyncWriteExt}; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut writer = Vec::new(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut writer = Vec::new(); /// - /// writer.write_i64_le(i64::MIN).await?; - /// writer.write_i64_le(i64::MAX).await?; + /// writer.write_i64_le(i64::MIN).await?; + /// writer.write_i64_le(i64::MAX).await?; /// - /// assert_eq!(writer, b"\x00\x00\x00\x00\x00\x00\x00\x80\xff\xff\xff\xff\xff\xff\xff\x7f"); - /// Ok(()) - /// } + /// assert_eq!(writer, b"\x00\x00\x00\x00\x00\x00\x00\x80\xff\xff\xff\xff\xff\xff\xff\x7f"); + /// Ok(()) + /// # } /// ``` fn write_i64_le(&mut self, n: i64) -> WriteI64Le; @@ -1085,18 +1103,18 @@ cfg_io_util! { /// ```rust /// use tokio::io::{self, AsyncWriteExt}; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut writer = Vec::new(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut writer = Vec::new(); /// - /// writer.write_u128_le(16947640962301618749969007319746179).await?; + /// writer.write_u128_le(16947640962301618749969007319746179).await?; /// - /// assert_eq!(writer, vec![ - /// 0x83, 0x86, 0x60, 0x4d, 0x95, 0x43, 0x03, 0x00, - /// 0x83, 0x86, 0x60, 0x4d, 0x95, 0x43, 0x03, 0x00, - /// ]); - /// Ok(()) - /// } + /// assert_eq!(writer, vec![ + /// 0x83, 0x86, 0x60, 0x4d, 0x95, 0x43, 0x03, 0x00, + /// 0x83, 0x86, 0x60, 0x4d, 0x95, 0x43, 0x03, 0x00, + /// ]); + /// Ok(()) + /// # } /// ``` fn write_u128_le(&mut self, n: u128) -> WriteU128Le; @@ -1125,18 +1143,18 @@ cfg_io_util! { /// ```rust /// use tokio::io::{self, AsyncWriteExt}; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut writer = Vec::new(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut writer = Vec::new(); /// - /// writer.write_i128_le(i128::MIN).await?; + /// writer.write_i128_le(i128::MIN).await?; /// - /// assert_eq!(writer, vec![ - /// 0, 0, 0, 0, 0, 0, 0, - /// 0, 0, 0, 0, 0, 0, 0, 0, 0x80 - /// ]); - /// Ok(()) - /// } + /// assert_eq!(writer, vec![ + /// 0, 0, 0, 0, 0, 0, 0, + /// 0, 0, 0, 0, 0, 0, 0, 0, 0x80 + /// ]); + /// Ok(()) + /// # } /// ``` fn write_i128_le(&mut self, n: i128) -> WriteI128Le; @@ -1165,15 +1183,15 @@ cfg_io_util! { /// ```rust /// use tokio::io::{self, AsyncWriteExt}; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut writer = Vec::new(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut writer = Vec::new(); /// - /// writer.write_f32_le(f32::MIN).await?; + /// writer.write_f32_le(f32::MIN).await?; /// - /// assert_eq!(writer, vec![0xff, 0xff, 0x7f, 0xff]); - /// Ok(()) - /// } + /// assert_eq!(writer, vec![0xff, 0xff, 0x7f, 0xff]); + /// Ok(()) + /// # } /// ``` fn write_f32_le(&mut self, n: f32) -> WriteF32Le; @@ -1202,17 +1220,17 @@ cfg_io_util! { /// ```rust /// use tokio::io::{self, AsyncWriteExt}; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let mut writer = Vec::new(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let mut writer = Vec::new(); /// - /// writer.write_f64_le(f64::MIN).await?; + /// writer.write_f64_le(f64::MIN).await?; /// - /// assert_eq!(writer, vec![ - /// 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff - /// ]); - /// Ok(()) - /// } + /// assert_eq!(writer, vec![ + /// 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff + /// ]); + /// Ok(()) + /// # } /// ``` fn write_f64_le(&mut self, n: f64) -> WriteF64Le; } @@ -1244,6 +1262,8 @@ cfg_io_util! { /// # Examples /// /// ```no_run + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::io::{self, BufWriter, AsyncWriteExt}; /// use tokio::fs::File; /// @@ -1256,6 +1276,7 @@ cfg_io_util! { /// buffer.flush().await?; /// Ok(()) /// } + /// # } /// ``` fn flush(&mut self) -> Flush<'_, Self> where @@ -1283,6 +1304,8 @@ cfg_io_util! { /// # Examples /// /// ```no_run + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::io::{self, BufWriter, AsyncWriteExt}; /// use tokio::fs::File; /// @@ -1295,6 +1318,7 @@ cfg_io_util! { /// buffer.shutdown().await?; /// Ok(()) /// } + /// # } /// ``` fn shutdown(&mut self) -> Shutdown<'_, Self> where diff --git a/tokio/src/io/util/empty.rs b/tokio/src/io/util/empty.rs index 8821f4f2..0cc6211c 100644 --- a/tokio/src/io/util/empty.rs +++ b/tokio/src/io/util/empty.rs @@ -39,12 +39,12 @@ cfg_io_util! { /// ``` /// use tokio::io::{self, AsyncReadExt}; /// - /// #[tokio::main] - /// async fn main() { + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { /// let mut buffer = String::new(); /// io::empty().read_to_string(&mut buffer).await.unwrap(); /// assert!(buffer.is_empty()); - /// } + /// # } /// ``` /// /// A convoluted way of getting the length of a buffer: @@ -52,12 +52,12 @@ cfg_io_util! { /// ``` /// use tokio::io::{self, AsyncWriteExt}; /// - /// #[tokio::main] - /// async fn main() { - /// let buffer = vec![1, 2, 3, 5, 8]; - /// let num_bytes = io::empty().write(&buffer).await.unwrap(); - /// assert_eq!(num_bytes, 5); - /// } + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let buffer = vec![1, 2, 3, 5, 8]; + /// let num_bytes = io::empty().write(&buffer).await.unwrap(); + /// assert_eq!(num_bytes, 5); + /// # } /// ``` pub fn empty() -> Empty { Empty { _p: () } diff --git a/tokio/src/io/util/repeat.rs b/tokio/src/io/util/repeat.rs index 33a8fd98..e5bce46a 100644 --- a/tokio/src/io/util/repeat.rs +++ b/tokio/src/io/util/repeat.rs @@ -37,12 +37,12 @@ cfg_io_util! { /// ``` /// use tokio::io::{self, AsyncReadExt}; /// - /// #[tokio::main] - /// async fn main() { - /// let mut buffer = [0; 3]; - /// io::repeat(0b101).read_exact(&mut buffer).await.unwrap(); - /// assert_eq!(buffer, [0b101, 0b101, 0b101]); - /// } + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let mut buffer = [0; 3]; + /// io::repeat(0b101).read_exact(&mut buffer).await.unwrap(); + /// assert_eq!(buffer, [0b101, 0b101, 0b101]); + /// # } /// ``` pub fn repeat(byte: u8) -> Repeat { Repeat { byte } diff --git a/tokio/src/io/util/sink.rs b/tokio/src/io/util/sink.rs index 01a4b111..28adc540 100644 --- a/tokio/src/io/util/sink.rs +++ b/tokio/src/io/util/sink.rs @@ -37,13 +37,13 @@ cfg_io_util! { /// ``` /// use tokio::io::{self, AsyncWriteExt}; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let buffer = vec![1, 2, 3, 5, 8]; - /// let num_bytes = io::sink().write(&buffer).await?; - /// assert_eq!(num_bytes, 5); - /// Ok(()) - /// } + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let buffer = vec![1, 2, 3, 5, 8]; + /// let num_bytes = io::sink().write(&buffer).await?; + /// assert_eq!(num_bytes, 5); + /// Ok(()) + /// # } /// ``` pub fn sink() -> Sink { Sink { _p: () } diff --git a/tokio/src/lib.rs b/tokio/src/lib.rs index 366ea04a..33ee9eb8 100644 --- a/tokio/src/lib.rs +++ b/tokio/src/lib.rs @@ -194,6 +194,8 @@ //! [`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. @@ -208,6 +210,7 @@ //! // panic. //! blocking_task.await.unwrap(); //! } +//! # } //! ``` //! //! If your code is CPU-bound and you wish to limit the number of threads used @@ -266,6 +269,8 @@ //! A simple TCP echo server: //! //! ```no_run +//! # #[cfg(not(target_family = "wasm"))] +//! # { //! use tokio::net::TcpListener; //! use tokio::io::{AsyncReadExt, AsyncWriteExt}; //! @@ -300,6 +305,7 @@ //! }); //! } //! } +//! # } //! ``` //! //! # Feature flags diff --git a/tokio/src/loom/std/barrier.rs b/tokio/src/loom/std/barrier.rs index a3f0ca0a..083fc45e 100644 --- a/tokio/src/loom/std/barrier.rs +++ b/tokio/src/loom/std/barrier.rs @@ -12,6 +12,8 @@ use std::time::{Duration, Instant}; /// # Examples /// /// ``` +/// # #[cfg(not(target_family = "wasm"))] +/// # { /// use std::sync::{Arc, Barrier}; /// use std::thread; /// @@ -31,6 +33,7 @@ use std::time::{Duration, Instant}; /// for handle in handles { /// handle.join().unwrap(); /// } +/// # } /// ``` pub(crate) struct Barrier { lock: Mutex, @@ -103,6 +106,8 @@ impl Barrier { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use std::sync::{Arc, Barrier}; /// use std::thread; /// @@ -122,6 +127,7 @@ impl Barrier { /// for handle in handles { /// handle.join().unwrap(); /// } + /// # } /// ``` pub(crate) fn wait(&self) -> BarrierWaitResult { let mut lock = self.lock.lock(); diff --git a/tokio/src/macros/join.rs b/tokio/src/macros/join.rs index 8c6ad545..1a62a979 100644 --- a/tokio/src/macros/join.rs +++ b/tokio/src/macros/join.rs @@ -64,19 +64,21 @@ macro_rules! doc { /// // more here /// } /// - /// #[tokio::main] - /// async fn main() { - /// let (first, second) = tokio::join!( - /// do_stuff_async(), - /// more_async_work()); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (first, second) = tokio::join!( + /// do_stuff_async(), + /// more_async_work()); /// - /// // do something with the values - /// } + /// // 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 /// } @@ -85,16 +87,17 @@ macro_rules! doc { /// // more here /// } /// - /// #[tokio::main] - /// async fn main() { - /// let (first, second) = tokio::join!( - /// biased; - /// do_stuff_async(), - /// more_async_work() - /// ); + /// # #[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 - /// } + /// // do something with the values + /// # } + /// # } /// ``` #[macro_export] diff --git a/tokio/src/macros/pin.rs b/tokio/src/macros/pin.rs index 7af9ce7d..d40220b0 100644 --- a/tokio/src/macros/pin.rs +++ b/tokio/src/macros/pin.rs @@ -31,13 +31,13 @@ /// // async logic here /// } /// -/// #[tokio::main] -/// async fn main() { -/// let future = my_async_fn(); -/// pin!(future); +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// let future = my_async_fn(); +/// pin!(future); /// -/// (&mut future).await; -/// } +/// (&mut future).await; +/// # } /// ``` /// /// Pinning is useful when using `select!` and stream operators that require `T: @@ -77,25 +77,25 @@ /// // async logic here /// } /// -/// #[tokio::main] -/// 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); -/// } +/// # #[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 @@ -108,18 +108,18 @@ /// // async logic here /// } /// -/// #[tokio::main] -/// async fn main() { -/// pin! { -/// let future1 = my_async_fn(); -/// let future2 = my_async_fn(); -/// } +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// pin! { +/// let future1 = my_async_fn(); +/// let future2 = my_async_fn(); +/// } /// -/// select! { -/// _ = &mut future1 => {} -/// _ = &mut future2 => {} -/// } +/// select! { +/// _ = &mut future1 => {} +/// _ = &mut future2 => {} /// } +/// # } /// ``` #[macro_export] macro_rules! pin { diff --git a/tokio/src/macros/select.rs b/tokio/src/macros/select.rs index 18cc44b9..351ca24e 100644 --- a/tokio/src/macros/select.rs +++ b/tokio/src/macros/select.rs @@ -158,17 +158,17 @@ macro_rules! doc { /// // more here /// } /// - /// #[tokio::main] - /// async fn main() { - /// tokio::select! { - /// _ = do_stuff_async() => { - /// println!("do_stuff_async() completed first") - /// } - /// _ = more_async_work() => { - /// println!("more_async_work() completed first") - /// } - /// }; - /// } + /// # #[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. @@ -176,18 +176,18 @@ macro_rules! doc { /// ``` /// use tokio_stream::{self as stream, StreamExt}; /// - /// #[tokio::main] - /// async fn main() { - /// let mut stream1 = stream::iter(vec![1, 2, 3]); - /// let mut stream2 = stream::iter(vec![4, 5, 6]); + /// # #[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(), - /// }; + /// let next = tokio::select! { + /// v = stream1.next() => v.unwrap(), + /// v = stream2.next() => v.unwrap(), + /// }; /// - /// assert!(next == 1 || next == 4); - /// } + /// assert!(next == 1 || next == 4); + /// # } /// ``` /// /// Collect the contents of two streams. In this example, we rely on pattern @@ -197,24 +197,24 @@ macro_rules! doc { /// ``` /// use tokio_stream::{self as stream, StreamExt}; /// - /// #[tokio::main] - /// async fn main() { - /// let mut stream1 = stream::iter(vec![1, 2, 3]); - /// let mut stream2 = stream::iter(vec![4, 5, 6]); + /// # #[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![]; + /// let mut values = vec![]; /// - /// loop { - /// tokio::select! { - /// Some(v) = stream1.next() => values.push(v), - /// Some(v) = stream2.next() => values.push(v), - /// else => break, - /// } + /// 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[..]); /// } + /// + /// values.sort(); + /// assert_eq!(&[1, 2, 3, 4, 5, 6], &values[..]); + /// # } /// ``` /// /// Using the same future in multiple `select!` expressions can be done by passing @@ -230,28 +230,28 @@ macro_rules! doc { /// use tokio_stream::{self as stream, StreamExt}; /// use tokio::time::{self, Duration}; /// - /// #[tokio::main] - /// 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"); + /// # #[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!`. @@ -259,73 +259,73 @@ macro_rules! doc { /// ``` /// use tokio::sync::oneshot; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx1, mut rx1) = oneshot::channel(); - /// let (tx2, mut rx2) = oneshot::channel(); + /// # #[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 { + /// tx1.send("first").unwrap(); + /// }); /// - /// tokio::spawn(async move { - /// tx2.send("second").unwrap(); - /// }); + /// tokio::spawn(async move { + /// tx2.send("second").unwrap(); + /// }); /// - /// let mut a = None; - /// let mut b = None; + /// 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()), - /// } + /// 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()); + /// let res = (a.unwrap(), b.unwrap()); /// - /// assert_eq!(res.0, "first"); - /// assert_eq!(res.1, "second"); - /// } + /// assert_eq!(res.0, "first"); + /// assert_eq!(res.1, "second"); + /// # } /// ``` /// /// Using the `biased;` mode to control polling order. /// /// ``` - /// #[tokio::main] - /// 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); - /// } + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let mut count = 0u8; /// - /// else => { - /// break; - /// } - /// }; - /// } + /// 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 @@ -344,24 +344,24 @@ macro_rules! doc { /// // do work /// } /// - /// #[tokio::main] - /// async fn main() { - /// let sleep = time::sleep(Duration::from_millis(50)); - /// tokio::pin!(sleep); + /// # #[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"); - /// } + /// 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!"); /// } + /// + /// panic!("This example shows how not to do it!"); + /// # } /// ``` /// /// In the above example, `sleep.is_elapsed()` may return `true` even if @@ -380,23 +380,23 @@ macro_rules! doc { /// // do work /// } /// - /// #[tokio::main] - /// async fn main() { - /// let sleep = time::sleep(Duration::from_millis(50)); - /// tokio::pin!(sleep); + /// # #[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"); - /// } + /// loop { + /// tokio::select! { + /// _ = &mut sleep => { + /// println!("operation timed out"); + /// break; + /// } + /// _ = some_async_work() => { + /// println!("operation completed"); /// } /// } /// } + /// # } /// ``` /// # Alternatives from the Ecosystem /// @@ -437,22 +437,21 @@ macro_rules! doc { /// // do work that is not cancel safe /// } /// - /// #[tokio::main] - /// 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 - /// } + /// # #[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` @@ -487,32 +486,32 @@ macro_rules! doc { /// Data(Vec), /// } /// - /// #[tokio::main] - /// 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, - /// } + /// # #[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 @@ -533,17 +532,17 @@ macro_rules! doc { /// ``` /// use futures_concurrency::future::Race; /// - /// #[tokio::main] - /// async fn main() { - /// let task_a = async { Ok("ok") }; - /// let task_b = async { Err("error") }; - /// let result = (task_a, task_b).race().await; + /// # #[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}"), - /// } + /// match result { + /// Ok(output) => println!("First task completed with: {output}"), + /// Err(err) => eprintln!("Error occurred: {err}"), /// } + /// # } /// ``` #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "macros")))] diff --git a/tokio/src/macros/try_join.rs b/tokio/src/macros/try_join.rs index c3185429..04f4825c 100644 --- a/tokio/src/macros/try_join.rs +++ b/tokio/src/macros/try_join.rs @@ -64,21 +64,21 @@ macro_rules! doc { /// # Ok(()) /// } /// - /// #[tokio::main] - /// async fn main() { - /// let res = tokio::try_join!( - /// do_stuff_async(), - /// more_async_work()); + /// # #[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); - /// } + /// match res { + /// Ok((first, second)) => { + /// // do something with the values + /// } + /// Err(err) => { + /// println!("processing failed; error = {}", err); /// } /// } + /// # } /// ``` /// /// Using `try_join!` with spawned tasks. @@ -104,20 +104,20 @@ macro_rules! doc { /// } /// } /// - /// #[tokio::main] - /// 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"); - /// } + /// # #[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. /// @@ -132,23 +132,23 @@ macro_rules! doc { /// # Ok(()) /// } /// - /// #[tokio::main] - /// async fn main() { - /// let res = tokio::try_join!( - /// biased; - /// do_stuff_async(), - /// more_async_work() - /// ); + /// # #[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); - /// } + /// match res { + /// Ok((first, second)) => { + /// // do something with the values + /// } + /// Err(err) => { + /// println!("processing failed; error = {}", err); /// } /// } + /// # } /// ``` #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "macros")))] diff --git a/tokio/src/runtime/builder.rs b/tokio/src/runtime/builder.rs index c11cd3b7..9aae69ab 100644 --- a/tokio/src/runtime/builder.rs +++ b/tokio/src/runtime/builder.rs @@ -31,6 +31,8 @@ use std::time::Duration; /// # Examples /// /// ``` +/// # #[cfg(not(target_family = "wasm"))] +/// # { /// use tokio::runtime::Builder; /// /// fn main() { @@ -44,6 +46,7 @@ use std::time::Duration; /// /// // use runtime ... /// } +/// # } /// ``` pub struct Builder { /// Runtime type @@ -152,6 +155,8 @@ cfg_unstable! { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime::{self, UnhandledPanic}; /// /// # pub fn main() { @@ -174,6 +179,7 @@ cfg_unstable! { /// assert!(task2.await.is_ok()); /// }) /// # } + /// # } /// ``` /// /// [`JoinHandle`]: struct@crate::task::JoinHandle @@ -324,12 +330,15 @@ impl Builder { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime; /// /// let rt = runtime::Builder::new_multi_thread() /// .enable_all() /// .build() /// .unwrap(); + /// # } /// ``` pub fn enable_all(&mut self) -> &mut Self { #[cfg(any( @@ -372,6 +381,8 @@ impl Builder { /// ## Multi threaded runtime with 4 threads /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime; /// /// // This will spawn a work-stealing runtime with 4 worker threads. @@ -381,6 +392,7 @@ impl Builder { /// .unwrap(); /// /// rt.spawn(async move {}); + /// # } /// ``` /// /// ## Current thread runtime (will only run on the current thread via `Runtime::block_on`) @@ -466,6 +478,8 @@ impl Builder { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// # use tokio::runtime; /// /// # pub fn main() { @@ -473,6 +487,7 @@ impl Builder { /// .thread_name("my-pool") /// .build(); /// # } + /// # } /// ``` pub fn thread_name(&mut self, val: impl Into) -> &mut Self { let val = val.into(); @@ -487,6 +502,8 @@ impl Builder { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// # use tokio::runtime; /// # use std::sync::atomic::{AtomicUsize, Ordering}; /// # pub fn main() { @@ -498,6 +515,7 @@ impl Builder { /// }) /// .build(); /// # } + /// # } /// ``` pub fn thread_name_fn(&mut self, f: F) -> &mut Self where @@ -518,6 +536,8 @@ impl Builder { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// # use tokio::runtime; /// /// # pub fn main() { @@ -525,6 +545,7 @@ impl Builder { /// .thread_stack_size(32 * 1024) /// .build(); /// # } + /// # } /// ``` pub fn thread_stack_size(&mut self, val: usize) -> &mut Self { self.thread_stack_size = Some(val); @@ -539,6 +560,8 @@ impl Builder { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// # use tokio::runtime; /// # pub fn main() { /// let runtime = runtime::Builder::new_multi_thread() @@ -547,6 +570,7 @@ impl Builder { /// }) /// .build(); /// # } + /// # } /// ``` #[cfg(not(loom))] pub fn on_thread_start(&mut self, f: F) -> &mut Self @@ -564,6 +588,8 @@ impl Builder { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// { /// # use tokio::runtime; /// # pub fn main() { /// let runtime = runtime::Builder::new_multi_thread() @@ -572,6 +598,7 @@ impl Builder { /// }) /// .build(); /// # } + /// # } /// ``` #[cfg(not(loom))] pub fn on_thread_stop(&mut self, f: F) -> &mut Self @@ -596,6 +623,8 @@ impl Builder { /// /// ## Multithreaded executor /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// # use std::sync::Arc; /// # use std::sync::atomic::{AtomicBool, Ordering}; /// # use tokio::runtime; @@ -622,6 +651,7 @@ impl Builder { /// barrier.wait().await; /// }) /// # } + /// # } /// ``` /// ## Current thread executor /// ``` @@ -672,6 +702,8 @@ impl Builder { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// # use tokio::runtime; /// # pub fn main() { /// let runtime = runtime::Builder::new_multi_thread() @@ -685,6 +717,7 @@ impl Builder { /// println!("Hello from Tokio!"); /// }) /// # } + /// # } /// ``` #[cfg(not(loom))] pub fn on_thread_unpark(&mut self, f: F) -> &mut Self @@ -760,6 +793,8 @@ impl Builder { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// # use std::sync::{atomic::AtomicUsize, Arc}; /// # use tokio::task::yield_now; /// # pub fn main() { @@ -778,6 +813,7 @@ impl Builder { /// let _ = rt.block_on(task); /// /// # } + /// # } /// ``` #[cfg(tokio_unstable)] #[cfg_attr(docsrs, doc(cfg(tokio_unstable)))] @@ -804,6 +840,8 @@ impl Builder { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// # use std::sync::{atomic::AtomicUsize, Arc}; /// # use tokio::task::yield_now; /// # pub fn main() { @@ -822,6 +860,7 @@ impl Builder { /// let _ = rt.block_on(task); /// /// # } + /// # } /// ``` #[cfg(tokio_unstable)] #[cfg_attr(docsrs, doc(cfg(tokio_unstable)))] @@ -889,6 +928,8 @@ impl Builder { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime::Builder; /// /// let rt = Builder::new_multi_thread().build().unwrap(); @@ -896,6 +937,7 @@ impl Builder { /// rt.block_on(async { /// println!("Hello from the Tokio runtime"); /// }); + /// # } /// ``` pub fn build(&mut self) -> io::Result { match &self.kind { @@ -961,6 +1003,8 @@ impl Builder { /// # Example /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// # use tokio::runtime; /// # use std::time::Duration; /// # pub fn main() { @@ -968,6 +1012,7 @@ impl Builder { /// .thread_keep_alive(Duration::from_millis(100)) /// .build(); /// # } + /// # } /// ``` pub fn thread_keep_alive(&mut self, duration: Duration) -> &mut Self { self.keep_alive = Some(duration); @@ -1000,12 +1045,15 @@ impl Builder { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// # use tokio::runtime; /// # pub fn main() { /// let rt = runtime::Builder::new_multi_thread() /// .global_queue_interval(31) /// .build(); /// # } + /// # } /// ``` #[track_caller] pub fn global_queue_interval(&mut self, val: u32) -> &mut Self { @@ -1034,12 +1082,15 @@ impl Builder { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// # use tokio::runtime; /// # pub fn main() { /// let rt = runtime::Builder::new_multi_thread() /// .event_interval(31) /// .build(); /// # } + /// # } /// ``` pub fn event_interval(&mut self, val: u32) -> &mut Self { self.event_interval = val; @@ -1144,12 +1195,15 @@ impl Builder { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime; /// /// let rt = runtime::Builder::new_multi_thread() /// .disable_lifo_slot() /// .build() /// .unwrap(); + /// # } /// ``` /// /// [tokio-rs/tokio-metrics]: https://github.com/tokio-rs/tokio-metrics @@ -1214,6 +1268,8 @@ impl Builder { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime; /// /// let rt = runtime::Builder::new_multi_thread() @@ -1226,6 +1282,7 @@ impl Builder { /// # assert_eq!(m.poll_time_histogram_num_buckets(), 10); /// # assert_eq!(m.poll_time_histogram_bucket_range(0), us(0)..us(100)); /// # assert_eq!(m.poll_time_histogram_bucket_range(1), us(100)..us(200)); + /// # } /// ``` /// /// [`Handle::metrics()`]: crate::runtime::Handle::metrics @@ -1260,6 +1317,8 @@ impl Builder { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime::{self, HistogramScale}; /// /// # #[allow(deprecated)] @@ -1268,6 +1327,7 @@ impl Builder { /// .metrics_poll_count_histogram_scale(HistogramScale::Log) /// .build() /// .unwrap(); + /// # } /// ``` #[deprecated(note = "use `metrics_poll_time_histogram_configuration`")] pub fn metrics_poll_count_histogram_scale(&mut self, histogram_scale: crate::runtime::HistogramScale) -> &mut Self { @@ -1284,6 +1344,8 @@ impl Builder { /// # Examples /// Configure a [`LogHistogram`] with [default configuration]: /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime; /// use tokio::runtime::{HistogramConfiguration, LogHistogram}; /// @@ -1294,10 +1356,13 @@ impl Builder { /// ) /// .build() /// .unwrap(); + /// # } /// ``` /// /// Configure a linear histogram with 100 buckets, each 10μs wide /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime; /// use std::time::Duration; /// use tokio::runtime::HistogramConfiguration; @@ -1309,6 +1374,7 @@ impl Builder { /// ) /// .build() /// .unwrap(); + /// # } /// ``` /// /// Configure a [`LogHistogram`] with the following settings: @@ -1316,6 +1382,8 @@ impl Builder { /// - Max error of 0.1 /// - No more than 1024 buckets /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use std::time::Duration; /// use tokio::runtime; /// use tokio::runtime::{HistogramConfiguration, LogHistogram}; @@ -1333,6 +1401,7 @@ impl Builder { /// ) /// .build() /// .unwrap(); + /// # } /// ``` /// /// When migrating from the legacy histogram ([`HistogramScale::Log`]) and wanting @@ -1382,6 +1451,8 @@ impl Builder { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime; /// use std::time::Duration; /// @@ -1391,6 +1462,7 @@ impl Builder { /// .metrics_poll_count_histogram_resolution(Duration::from_micros(100)) /// .build() /// .unwrap(); + /// # } /// ``` #[deprecated(note = "use `metrics_poll_time_histogram_configuration`")] pub fn metrics_poll_count_histogram_resolution(&mut self, resolution: Duration) -> &mut Self { @@ -1417,6 +1489,8 @@ impl Builder { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime; /// /// # #[allow(deprecated)] @@ -1425,6 +1499,7 @@ impl Builder { /// .metrics_poll_count_histogram_buckets(15) /// .build() /// .unwrap(); + /// # } /// ``` #[deprecated(note = "use `metrics_poll_time_histogram_configuration`")] pub fn metrics_poll_count_histogram_buckets(&mut self, buckets: usize) -> &mut Self { @@ -1576,12 +1651,15 @@ cfg_time! { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime; /// /// let rt = runtime::Builder::new_multi_thread() /// .enable_time() /// .build() /// .unwrap(); + /// # } /// ``` pub fn enable_time(&mut self) -> &mut Self { self.enable_time = true; diff --git a/tokio/src/runtime/handle.rs b/tokio/src/runtime/handle.rs index 8f9d9509..95803a80 100644 --- a/tokio/src/runtime/handle.rs +++ b/tokio/src/runtime/handle.rs @@ -52,6 +52,8 @@ impl Handle { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime::Runtime; /// /// let rt = Runtime::new().unwrap(); @@ -60,12 +62,13 @@ impl Handle { /// tokio::spawn(async { /// println!("Hello world!"); /// }); + /// # } /// ``` /// /// Do **not** do the following, this shows a scenario that will result in a /// panic and possible memory leak. /// - /// ```should_panic + /// ```should_panic,ignore-wasm /// use tokio::runtime::Runtime; /// /// let rt1 = Runtime::new().unwrap(); @@ -106,6 +109,8 @@ impl Handle { /// block or function running on that runtime. /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// # use std::thread; /// # use tokio::runtime::Runtime; /// # fn dox() { @@ -134,6 +139,7 @@ impl Handle { /// # handle.join().unwrap(); /// # }); /// # } + /// # } /// ``` #[track_caller] pub fn current() -> Self { @@ -170,6 +176,8 @@ impl Handle { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime::Runtime; /// /// # fn dox() { @@ -183,6 +191,7 @@ impl Handle { /// println!("now running on a worker thread"); /// }); /// # } + /// # } /// ``` #[track_caller] pub fn spawn(&self, future: F) -> JoinHandle @@ -204,6 +213,8 @@ impl Handle { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime::Runtime; /// /// # fn dox() { @@ -217,6 +228,8 @@ impl Handle { /// println!("now running on a worker thread"); /// }); /// # } + /// # } + /// ``` #[track_caller] pub fn spawn_blocking(&self, func: F) -> JoinHandle where @@ -256,6 +269,8 @@ impl Handle { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime::Runtime; /// /// // Create the runtime @@ -268,11 +283,14 @@ impl Handle { /// handle.block_on(async { /// println!("hello"); /// }); + /// # } /// ``` /// /// Or using `Handle::current`: /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime::Handle; /// /// #[tokio::main] @@ -285,6 +303,7 @@ impl Handle { /// }); /// }); /// } + /// # } /// ``` /// /// [`JoinError`]: struct@crate::task::JoinError @@ -387,12 +406,15 @@ impl Handle { /// ``` /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime::{Handle, RuntimeFlavor}; /// /// #[tokio::main(flavor = "multi_thread", worker_threads = 4)] /// async fn main() { /// assert_eq!(RuntimeFlavor::MultiThread, Handle::current().runtime_flavor()); /// } + /// # } /// ``` pub fn runtime_flavor(&self) -> RuntimeFlavor { match self.inner { diff --git a/tokio/src/runtime/id.rs b/tokio/src/runtime/id.rs index 8c6df7fc..dc223bdc 100644 --- a/tokio/src/runtime/id.rs +++ b/tokio/src/runtime/id.rs @@ -16,12 +16,15 @@ use std::num::{NonZeroU32, NonZeroU64}; /// # Examples /// /// ``` +/// # #[cfg(not(target_family = "wasm"))] +/// # { /// use tokio::runtime::Handle; /// /// #[tokio::main(flavor = "multi_thread", worker_threads = 4)] /// async fn main() { /// println!("Current runtime id: {}", Handle::current().id()); /// } +/// # } /// ``` /// /// **Note**: This is an [unstable API][unstable]. The public API of this type diff --git a/tokio/src/runtime/local_runtime/runtime.rs b/tokio/src/runtime/local_runtime/runtime.rs index 2e9d14e1..62c3c582 100644 --- a/tokio/src/runtime/local_runtime/runtime.rs +++ b/tokio/src/runtime/local_runtime/runtime.rs @@ -313,6 +313,8 @@ impl LocalRuntime { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime::LocalRuntime; /// use tokio::task; /// @@ -330,6 +332,7 @@ impl LocalRuntime { /// /// runtime.shutdown_timeout(Duration::from_millis(100)); /// } + /// # } /// ``` pub fn shutdown_timeout(mut self, duration: Duration) { // Wakeup and shutdown all the worker threads diff --git a/tokio/src/runtime/metrics/runtime.rs b/tokio/src/runtime/metrics/runtime.rs index 6302457b..adb84416 100644 --- a/tokio/src/runtime/metrics/runtime.rs +++ b/tokio/src/runtime/metrics/runtime.rs @@ -37,13 +37,13 @@ impl RuntimeMetrics { /// ``` /// use tokio::runtime::Handle; /// - /// #[tokio::main] - /// async fn main() { - /// let metrics = Handle::current().metrics(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let metrics = Handle::current().metrics(); /// - /// let n = metrics.num_workers(); - /// println!("Runtime is using {} workers", n); - /// } + /// let n = metrics.num_workers(); + /// println!("Runtime is using {} workers", n); + /// # } /// ``` pub fn num_workers(&self) -> usize { self.handle.inner.num_workers() @@ -59,13 +59,13 @@ impl RuntimeMetrics { /// ``` /// use tokio::runtime::Handle; /// - /// #[tokio::main] - /// async fn main() { - /// let metrics = Handle::current().metrics(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let metrics = Handle::current().metrics(); /// - /// let n = metrics.num_alive_tasks(); - /// println!("Runtime has {} alive tasks", n); - /// } + /// let n = metrics.num_alive_tasks(); + /// println!("Runtime has {} alive tasks", n); + /// # } /// ``` pub fn num_alive_tasks(&self) -> usize { self.handle.inner.num_alive_tasks() @@ -85,13 +85,13 @@ impl RuntimeMetrics { /// ``` /// use tokio::runtime::Handle; /// - /// #[tokio::main] - /// async fn main() { - /// let metrics = Handle::current().metrics(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let metrics = Handle::current().metrics(); /// - /// let n = metrics.global_queue_depth(); - /// println!("{} tasks currently pending in the runtime's global queue", n); - /// } + /// let n = metrics.global_queue_depth(); + /// println!("{} tasks currently pending in the runtime's global queue", n); + /// # } /// ``` pub fn global_queue_depth(&self) -> usize { self.handle.inner.injection_queue_depth() @@ -126,13 +126,13 @@ impl RuntimeMetrics { /// ``` /// use tokio::runtime::Handle; /// - /// #[tokio::main] - /// async fn main() { - /// let metrics = Handle::current().metrics(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let metrics = Handle::current().metrics(); /// - /// let n = metrics.worker_total_busy_duration(0); - /// println!("worker 0 was busy for a total of {:?}", n); - /// } + /// let n = metrics.worker_total_busy_duration(0); + /// println!("worker 0 was busy for a total of {:?}", n); + /// # } /// ``` pub fn worker_total_busy_duration(&self, worker: usize) -> Duration { let nanos = self @@ -171,13 +171,13 @@ impl RuntimeMetrics { /// ``` /// use tokio::runtime::Handle; /// - /// #[tokio::main] - /// async fn main() { - /// let metrics = Handle::current().metrics(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let metrics = Handle::current().metrics(); /// - /// let n = metrics.worker_park_count(0); - /// println!("worker 0 parked {} times", n); - /// } + /// let n = metrics.worker_park_count(0); + /// println!("worker 0 parked {} times", n); + /// # } /// ``` pub fn worker_park_count(&self, worker: usize) -> u64 { self.handle @@ -219,19 +219,19 @@ impl RuntimeMetrics { /// ``` /// use tokio::runtime::Handle; /// - /// #[tokio::main] - /// async fn main() { - /// let metrics = Handle::current().metrics(); - /// let n = metrics.worker_park_unpark_count(0); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let metrics = Handle::current().metrics(); + /// let n = metrics.worker_park_unpark_count(0); /// - /// println!("worker 0 parked and unparked {} times", n); + /// println!("worker 0 parked and unparked {} times", n); /// - /// if n % 2 == 0 { - /// println!("worker 0 is active"); - /// } else { - /// println!("worker 0 is parked"); - /// } + /// if n % 2 == 0 { + /// println!("worker 0 is active"); + /// } else { + /// println!("worker 0 is parked"); /// } + /// # } /// ``` pub fn worker_park_unpark_count(&self, worker: usize) -> u64 { self.handle @@ -252,19 +252,22 @@ impl RuntimeMetrics { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime::Handle; /// - /// #[tokio::main] - /// async fn main() { - /// let _ = tokio::task::spawn_blocking(move || { - /// // Stand-in for compute-heavy work or using synchronous APIs - /// 1 + 1 - /// }).await; - /// let metrics = Handle::current().metrics(); - /// - /// let n = metrics.num_blocking_threads(); - /// println!("Runtime has created {} threads", n); - /// } + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let _ = tokio::task::spawn_blocking(move || { + /// // Stand-in for compute-heavy work or using synchronous APIs + /// 1 + 1 + /// }).await; + /// let metrics = Handle::current().metrics(); + /// + /// let n = metrics.num_blocking_threads(); + /// println!("Runtime has created {} threads", n); + /// # } + /// # } /// ``` pub fn num_blocking_threads(&self) -> usize { self.handle.inner.num_blocking_threads() @@ -282,6 +285,8 @@ impl RuntimeMetrics { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime::Handle; /// /// #[tokio::main] @@ -295,6 +300,7 @@ impl RuntimeMetrics { /// let n = metrics.num_idle_blocking_threads(); /// println!("Runtime has {} idle blocking thread pool threads", n); /// } + /// # } /// ``` pub fn num_idle_blocking_threads(&self) -> usize { self.handle.inner.num_idle_blocking_threads() @@ -328,13 +334,13 @@ impl RuntimeMetrics { /// ``` /// use tokio::runtime::Handle; /// - /// #[tokio::main] - /// async fn main() { - /// let metrics = Handle::current().metrics(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let metrics = Handle::current().metrics(); /// - /// let id = metrics.worker_thread_id(0); - /// println!("worker 0 has id {:?}", id); - /// } + /// let id = metrics.worker_thread_id(0); + /// println!("worker 0 has id {:?}", id); + /// # } /// ``` pub fn worker_thread_id(&self, worker: usize) -> Option { self.handle @@ -376,13 +382,13 @@ impl RuntimeMetrics { /// ``` /// use tokio::runtime::Handle; /// - /// #[tokio::main] - /// async fn main() { - /// let metrics = Handle::current().metrics(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let metrics = Handle::current().metrics(); /// - /// let n = metrics.worker_local_queue_depth(0); - /// println!("{} tasks currently pending in worker 0's local queue", n); - /// } + /// let n = metrics.worker_local_queue_depth(0); + /// println!("{} tasks currently pending in worker 0's local queue", n); + /// # } /// ``` pub fn worker_local_queue_depth(&self, worker: usize) -> usize { self.handle.inner.worker_local_queue_depth(worker) @@ -550,13 +556,13 @@ impl RuntimeMetrics { /// ``` /// use tokio::runtime::Handle; /// - /// #[tokio::main] - /// async fn main() { - /// let metrics = Handle::current().metrics(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let metrics = Handle::current().metrics(); /// - /// let n = metrics.blocking_queue_depth(); - /// println!("{} tasks currently pending in the blocking thread pool", n); - /// } + /// let n = metrics.blocking_queue_depth(); + /// println!("{} tasks currently pending in the blocking thread pool", n); + /// # } /// ``` pub fn blocking_queue_depth(&self) -> usize { self.handle.inner.blocking_queue_depth() @@ -580,13 +586,13 @@ impl RuntimeMetrics { /// ``` /// use tokio::runtime::Handle; /// - /// #[tokio::main] - /// async fn main() { - /// let metrics = Handle::current().metrics(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let metrics = Handle::current().metrics(); /// - /// let n = metrics.spawned_tasks_count(); - /// println!("Runtime has had {} tasks spawned", n); - /// } + /// let n = metrics.spawned_tasks_count(); + /// println!("Runtime has had {} tasks spawned", n); + /// # } /// ``` pub fn spawned_tasks_count(&self) -> u64 { self.handle.inner.spawned_tasks_count() @@ -608,13 +614,13 @@ impl RuntimeMetrics { /// ``` /// use tokio::runtime::Handle; /// - /// #[tokio::main] - /// async fn main() { - /// let metrics = Handle::current().metrics(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let metrics = Handle::current().metrics(); /// - /// let n = metrics.remote_schedule_count(); - /// println!("{} tasks were scheduled from outside the runtime", n); - /// } + /// let n = metrics.remote_schedule_count(); + /// println!("{} tasks were scheduled from outside the runtime", n); + /// # } /// ``` pub fn remote_schedule_count(&self) -> u64 { self.handle @@ -666,13 +672,13 @@ impl RuntimeMetrics { /// ``` /// use tokio::runtime::Handle; /// - /// #[tokio::main] - /// async fn main() { - /// let metrics = Handle::current().metrics(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let metrics = Handle::current().metrics(); /// - /// let n = metrics.worker_noop_count(0); - /// println!("worker 0 had {} no-op unparks", n); - /// } + /// let n = metrics.worker_noop_count(0); + /// println!("worker 0 had {} no-op unparks", n); + /// # } /// ``` pub fn worker_noop_count(&self, worker: usize) -> u64 { self.handle @@ -712,13 +718,13 @@ impl RuntimeMetrics { /// ``` /// use tokio::runtime::Handle; /// - /// #[tokio::main] - /// async fn main() { - /// let metrics = Handle::current().metrics(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let metrics = Handle::current().metrics(); /// - /// let n = metrics.worker_steal_count(0); - /// println!("worker 0 has stolen {} tasks", n); - /// } + /// let n = metrics.worker_steal_count(0); + /// println!("worker 0 has stolen {} tasks", n); + /// # } /// ``` pub fn worker_steal_count(&self, worker: usize) -> u64 { self.handle @@ -758,13 +764,13 @@ impl RuntimeMetrics { /// ``` /// use tokio::runtime::Handle; /// - /// #[tokio::main] - /// async fn main() { - /// let metrics = Handle::current().metrics(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let metrics = Handle::current().metrics(); /// - /// let n = metrics.worker_steal_operations(0); - /// println!("worker 0 has stolen tasks {} times", n); - /// } + /// let n = metrics.worker_steal_operations(0); + /// println!("worker 0 has stolen tasks {} times", n); + /// # } /// ``` pub fn worker_steal_operations(&self, worker: usize) -> u64 { self.handle @@ -799,13 +805,13 @@ impl RuntimeMetrics { /// ``` /// use tokio::runtime::Handle; /// - /// #[tokio::main] - /// async fn main() { - /// let metrics = Handle::current().metrics(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let metrics = Handle::current().metrics(); /// - /// let n = metrics.worker_poll_count(0); - /// println!("worker 0 has polled {} tasks", n); - /// } + /// let n = metrics.worker_poll_count(0); + /// println!("worker 0 has polled {} tasks", n); + /// # } /// ``` pub fn worker_poll_count(&self, worker: usize) -> u64 { self.handle @@ -844,13 +850,13 @@ impl RuntimeMetrics { /// ``` /// use tokio::runtime::Handle; /// - /// #[tokio::main] - /// async fn main() { - /// let metrics = Handle::current().metrics(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let metrics = Handle::current().metrics(); /// - /// let n = metrics.worker_local_schedule_count(0); - /// println!("{} tasks were scheduled on the worker's local queue", n); - /// } + /// let n = metrics.worker_local_schedule_count(0); + /// println!("{} tasks were scheduled on the worker's local queue", n); + /// # } /// ``` pub fn worker_local_schedule_count(&self, worker: usize) -> u64 { self.handle @@ -890,13 +896,13 @@ impl RuntimeMetrics { /// ``` /// use tokio::runtime::Handle; /// - /// #[tokio::main] - /// async fn main() { - /// let metrics = Handle::current().metrics(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let metrics = Handle::current().metrics(); /// - /// let n = metrics.worker_overflow_count(0); - /// println!("worker 0 has overflowed its queue {} times", n); - /// } + /// let n = metrics.worker_overflow_count(0); + /// println!("worker 0 has overflowed its queue {} times", n); + /// # } /// ``` pub fn worker_overflow_count(&self, worker: usize) -> u64 { self.handle @@ -999,13 +1005,13 @@ impl RuntimeMetrics { /// ``` /// use tokio::runtime::Handle; /// - /// #[tokio::main] - /// async fn main() { - /// let metrics = Handle::current().metrics(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let metrics = Handle::current().metrics(); /// - /// let n = metrics.worker_mean_poll_time(0); - /// println!("worker 0 has a mean poll time of {:?}", n); - /// } + /// let n = metrics.worker_mean_poll_time(0); + /// println!("worker 0 has a mean poll time of {:?}", n); + /// # } /// ``` #[track_caller] pub fn worker_mean_poll_time(&self, worker: usize) -> Duration { diff --git a/tokio/src/runtime/mod.rs b/tokio/src/runtime/mod.rs index 031fde5d..3a74dda2 100644 --- a/tokio/src/runtime/mod.rs +++ b/tokio/src/runtime/mod.rs @@ -19,6 +19,8 @@ //! used. //! //! ```no_run +//! # #[cfg(not(target_family = "wasm"))] +//! # { //! use tokio::net::TcpListener; //! use tokio::io::{AsyncReadExt, AsyncWriteExt}; //! @@ -53,6 +55,7 @@ //! }); //! } //! } +//! # } //! ``` //! //! From within the context of the runtime, additional tasks are spawned using @@ -62,6 +65,8 @@ //! 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; @@ -102,6 +107,7 @@ //! } //! }) //! } +//! # } //! ``` //! //! ## Runtime Configurations @@ -118,11 +124,14 @@ //! 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> { //! let threaded_rt = runtime::Runtime::new()?; //! # Ok(()) } +//! # } //! ``` //! //! Most applications should use the multi-thread scheduler, except in some diff --git a/tokio/src/runtime/runtime.rs b/tokio/src/runtime/runtime.rs index 1bbb0205..120f7710 100644 --- a/tokio/src/runtime/runtime.rs +++ b/tokio/src/runtime/runtime.rs @@ -184,6 +184,8 @@ impl Runtime { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime::Runtime; /// /// let rt = Runtime::new() @@ -192,6 +194,7 @@ impl Runtime { /// let handle = rt.handle(); /// /// // Use the handle... + /// # } /// ``` pub fn handle(&self) -> &Handle { &self.handle @@ -214,6 +217,8 @@ impl Runtime { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime::Runtime; /// /// # fn dox() { @@ -225,6 +230,7 @@ impl Runtime { /// println!("now running on a worker thread"); /// }); /// # } + /// # } /// ``` #[track_caller] pub fn spawn(&self, future: F) -> JoinHandle @@ -247,6 +253,8 @@ impl Runtime { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime::Runtime; /// /// # fn dox() { @@ -258,6 +266,7 @@ impl Runtime { /// println!("now running on a worker thread"); /// }); /// # } + /// # } /// ``` #[track_caller] pub fn spawn_blocking(&self, func: F) -> JoinHandle @@ -309,6 +318,8 @@ impl Runtime { /// # Examples /// /// ```no_run + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime::Runtime; /// /// // Create the runtime @@ -318,6 +329,7 @@ impl Runtime { /// rt.block_on(async { /// println!("hello"); /// }); + /// # } /// ``` /// /// [handle]: fn@Handle::block_on @@ -372,6 +384,8 @@ impl Runtime { /// # Example /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime::Runtime; /// use tokio::task::JoinHandle; /// @@ -394,6 +408,7 @@ impl Runtime { /// // Wait for the task before we end the test. /// rt.block_on(handle).unwrap(); /// } + /// # } /// ``` pub fn enter(&self) -> EnterGuard<'_> { self.handle.enter() @@ -407,6 +422,8 @@ impl Runtime { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime::Runtime; /// use tokio::task; /// @@ -425,6 +442,7 @@ impl Runtime { /// /// runtime.shutdown_timeout(Duration::from_millis(100)); /// } + /// # } /// ``` pub fn shutdown_timeout(mut self, duration: Duration) { // Wakeup and shutdown all the worker threads @@ -448,6 +466,8 @@ impl Runtime { /// This function is equivalent to calling `shutdown_timeout(Duration::from_nanos(0))`. /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime::Runtime; /// /// fn main() { @@ -459,6 +479,7 @@ impl Runtime { /// inner_runtime.shutdown_background(); /// }); /// } + /// # } /// ``` pub fn shutdown_background(self) { self.shutdown_timeout(Duration::from_nanos(0)); diff --git a/tokio/src/runtime/task/error.rs b/tokio/src/runtime/task/error.rs index b3bd8195..552b4efd 100644 --- a/tokio/src/runtime/task/error.rs +++ b/tokio/src/runtime/task/error.rs @@ -46,6 +46,8 @@ impl JoinError { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use std::panic; /// /// #[tokio::main] @@ -56,6 +58,7 @@ impl JoinError { /// /// assert!(err.is_panic()); /// } + /// # } /// ``` pub fn is_panic(&self) -> bool { matches!(&self.repr, Repr::Panic(_)) @@ -71,7 +74,7 @@ impl JoinError { /// /// # Examples /// - /// ```should_panic + /// ```should_panic,ignore-wasm /// use std::panic; /// /// #[tokio::main] @@ -98,7 +101,7 @@ impl JoinError { /// /// # Examples /// - /// ```should_panic + /// ```should_panic,ignore-wasm /// use std::panic; /// /// #[tokio::main] diff --git a/tokio/src/runtime/task/join.rs b/tokio/src/runtime/task/join.rs index db1df2eb..f90bc85e 100644 --- a/tokio/src/runtime/task/join.rs +++ b/tokio/src/runtime/task/join.rs @@ -91,21 +91,23 @@ cfg_rt! { /// use tokio::task; /// use std::io; /// - /// #[tokio::main] - /// async fn main() -> io::Result<()> { - /// let join_handle: task::JoinHandle> = tokio::spawn(async { - /// Ok(5 + 3) - /// }); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> io::Result<()> { + /// let join_handle: task::JoinHandle> = tokio::spawn(async { + /// Ok(5 + 3) + /// }); /// - /// let result = join_handle.await??; - /// assert_eq!(result, 8); - /// Ok(()) - /// } + /// let result = join_handle.await??; + /// assert_eq!(result, 8); + /// Ok(()) + /// # } /// ``` /// /// If the task panics, the error is a [`JoinError`] that contains the panic: /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::task; /// use std::io; /// use std::panic; @@ -120,7 +122,7 @@ cfg_rt! { /// assert!(err.is_panic()); /// Ok(()) /// } - /// + /// # } /// ``` /// Child being detached and outliving its parent: /// @@ -129,7 +131,8 @@ cfg_rt! { /// use tokio::time; /// use std::time::Duration; /// - /// # #[tokio::main] async fn main() { + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { /// let original_task = task::spawn(async { /// let _detached_task = task::spawn(async { /// // Here we sleep to make sure that the first task returns before. diff --git a/tokio/src/sync/barrier.rs b/tokio/src/sync/barrier.rs index aa2f9e0c..00fc212d 100644 --- a/tokio/src/sync/barrier.rs +++ b/tokio/src/sync/barrier.rs @@ -6,7 +6,7 @@ use crate::util::trace; /// A barrier enables multiple tasks to synchronize the beginning of some computation. /// /// ``` -/// # #[tokio::main] +/// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// use tokio::sync::Barrier; /// use std::sync::Arc; diff --git a/tokio/src/sync/broadcast.rs b/tokio/src/sync/broadcast.rs index cf1ae6cc..8a1cb5af 100644 --- a/tokio/src/sync/broadcast.rs +++ b/tokio/src/sync/broadcast.rs @@ -73,24 +73,24 @@ //! ``` //! use tokio::sync::broadcast; //! -//! #[tokio::main] -//! async fn main() { -//! let (tx, mut rx1) = broadcast::channel(16); -//! let mut rx2 = tx.subscribe(); +//! # #[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!(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); -//! }); +//! 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(); -//! } +//! tx.send(10).unwrap(); +//! tx.send(20).unwrap(); +//! # } //! ``` //! //! Handling lag @@ -98,22 +98,22 @@ //! ``` //! use tokio::sync::broadcast; //! -//! #[tokio::main] -//! async fn main() { -//! let (tx, mut rx) = broadcast::channel(2); +//! # #[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(); +//! tx.send(10).unwrap(); +//! tx.send(20).unwrap(); +//! tx.send(30).unwrap(); //! -//! // The receiver lagged behind -//! assert!(rx.recv().await.is_err()); +//! // The receiver lagged behind +//! assert!(rx.recv().await.is_err()); //! -//! // At this point, we can abort or continue with lost messages +//! // 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()); -//! } +//! assert_eq!(20, rx.recv().await.unwrap()); +//! assert_eq!(30, rx.recv().await.unwrap()); +//! # } //! ``` use crate::loom::cell::UnsafeCell; @@ -141,24 +141,24 @@ use std::task::{ready, Context, Poll, Waker}; /// ``` /// use tokio::sync::broadcast; /// -/// #[tokio::main] -/// async fn main() { -/// let (tx, mut rx1) = broadcast::channel(16); -/// let mut rx2 = tx.subscribe(); +/// # #[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!(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); -/// }); +/// 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(); -/// } +/// tx.send(10).unwrap(); +/// tx.send(20).unwrap(); +/// # } /// ``` /// /// [`broadcast`]: crate::sync::broadcast @@ -183,18 +183,18 @@ pub struct Sender { /// ``` /// use tokio::sync::broadcast::channel; /// -/// #[tokio::main] -/// async fn main() { -/// let (tx, _rx) = channel::(15); -/// let tx_weak = tx.downgrade(); +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// let (tx, _rx) = channel::(15); +/// let tx_weak = tx.downgrade(); /// -/// // Upgrading will succeed because `tx` still exists. -/// assert!(tx_weak.upgrade().is_some()); +/// // 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()); -/// } +/// // If we drop `tx`, then it will fail. +/// drop(tx); +/// assert!(tx_weak.clone().upgrade().is_none()); +/// # } /// ``` pub struct WeakSender { shared: Arc>, @@ -215,24 +215,24 @@ pub struct WeakSender { /// ``` /// use tokio::sync::broadcast; /// -/// #[tokio::main] -/// async fn main() { -/// let (tx, mut rx1) = broadcast::channel(16); -/// let mut rx2 = tx.subscribe(); +/// # #[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!(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); -/// }); +/// 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(); -/// } +/// tx.send(10).unwrap(); +/// tx.send(20).unwrap(); +/// # } /// ``` /// /// [`broadcast`]: crate::sync::broadcast @@ -478,24 +478,24 @@ const MAX_RECEIVERS: usize = usize::MAX >> 2; /// ``` /// use tokio::sync::broadcast; /// -/// #[tokio::main] -/// async fn main() { -/// let (tx, mut rx1) = broadcast::channel(16); -/// let mut rx2 = tx.subscribe(); +/// # #[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!(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); -/// }); +/// 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(); -/// } +/// tx.send(10).unwrap(); +/// tx.send(20).unwrap(); +/// # } /// ``` /// /// # Panics @@ -609,24 +609,24 @@ impl Sender { /// ``` /// use tokio::sync::broadcast; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx1) = broadcast::channel(16); - /// let mut rx2 = tx.subscribe(); + /// # #[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!(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); - /// }); + /// 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(); - /// } + /// tx.send(10).unwrap(); + /// tx.send(20).unwrap(); + /// # } /// ``` pub fn send(&self, value: T) -> Result> { let mut tail = self.shared.tail.lock(); @@ -674,20 +674,20 @@ impl Sender { /// ``` /// use tokio::sync::broadcast; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, _rx) = broadcast::channel(16); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, _rx) = broadcast::channel(16); /// - /// // Will not be seen - /// tx.send(10).unwrap(); + /// // Will not be seen + /// tx.send(10).unwrap(); /// - /// let mut rx = tx.subscribe(); + /// let mut rx = tx.subscribe(); /// - /// tx.send(20).unwrap(); + /// tx.send(20).unwrap(); /// - /// let value = rx.recv().await.unwrap(); - /// assert_eq!(20, value); - /// } + /// let value = rx.recv().await.unwrap(); + /// assert_eq!(20, value); + /// # } /// ``` pub fn subscribe(&self) -> Receiver { let shared = self.shared.clone(); @@ -722,26 +722,26 @@ impl Sender { /// ``` /// use tokio::sync::broadcast; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx1) = broadcast::channel(16); - /// let mut rx2 = tx.subscribe(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx1) = broadcast::channel(16); + /// let mut rx2 = tx.subscribe(); /// - /// tx.send(10).unwrap(); - /// tx.send(20).unwrap(); - /// tx.send(30).unwrap(); + /// tx.send(10).unwrap(); + /// tx.send(20).unwrap(); + /// tx.send(30).unwrap(); /// - /// assert_eq!(tx.len(), 3); + /// assert_eq!(tx.len(), 3); /// - /// rx1.recv().await.unwrap(); + /// rx1.recv().await.unwrap(); /// - /// // The len is still 3 since rx2 hasn't seen the first value yet. - /// assert_eq!(tx.len(), 3); + /// // The len is still 3 since rx2 hasn't seen the first value yet. + /// assert_eq!(tx.len(), 3); /// - /// rx2.recv().await.unwrap(); + /// rx2.recv().await.unwrap(); /// - /// assert_eq!(tx.len(), 2); - /// } + /// assert_eq!(tx.len(), 2); + /// # } /// ``` pub fn len(&self) -> usize { let tail = self.shared.tail.lock(); @@ -769,26 +769,26 @@ impl Sender { /// ``` /// use tokio::sync::broadcast; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx1) = broadcast::channel(16); - /// let mut rx2 = tx.subscribe(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx1) = broadcast::channel(16); + /// let mut rx2 = tx.subscribe(); /// - /// assert!(tx.is_empty()); + /// assert!(tx.is_empty()); /// - /// tx.send(10).unwrap(); + /// tx.send(10).unwrap(); /// - /// assert!(!tx.is_empty()); + /// assert!(!tx.is_empty()); /// - /// rx1.recv().await.unwrap(); + /// rx1.recv().await.unwrap(); /// - /// // The queue is still not empty since rx2 hasn't seen the value. - /// assert!(!tx.is_empty()); + /// // The queue is still not empty since rx2 hasn't seen the value. + /// assert!(!tx.is_empty()); /// - /// rx2.recv().await.unwrap(); + /// rx2.recv().await.unwrap(); /// - /// assert!(tx.is_empty()); - /// } + /// assert!(tx.is_empty()); + /// # } /// ``` pub fn is_empty(&self) -> bool { let tail = self.shared.tail.lock(); @@ -820,18 +820,18 @@ impl Sender { /// ``` /// use tokio::sync::broadcast; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, _rx1) = broadcast::channel(16); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, _rx1) = broadcast::channel(16); /// - /// assert_eq!(1, tx.receiver_count()); + /// assert_eq!(1, tx.receiver_count()); /// - /// let mut _rx2 = tx.subscribe(); + /// let mut _rx2 = tx.subscribe(); /// - /// assert_eq!(2, tx.receiver_count()); + /// assert_eq!(2, tx.receiver_count()); /// - /// tx.send(10).unwrap(); - /// } + /// tx.send(10).unwrap(); + /// # } /// ``` pub fn receiver_count(&self) -> usize { let tail = self.shared.tail.lock(); @@ -845,17 +845,17 @@ impl Sender { /// ``` /// use tokio::sync::broadcast; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, _rx) = broadcast::channel::<()>(16); - /// let tx2 = tx.clone(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, _rx) = broadcast::channel::<()>(16); + /// let tx2 = tx.clone(); /// - /// assert!(tx.same_channel(&tx2)); + /// assert!(tx.same_channel(&tx2)); /// - /// let (tx3, _rx3) = broadcast::channel::<()>(16); + /// let (tx3, _rx3) = broadcast::channel::<()>(16); /// - /// assert!(!tx3.same_channel(&tx2)); - /// } + /// assert!(!tx3.same_channel(&tx2)); + /// # } /// ``` pub fn same_channel(&self, other: &Self) -> bool { Arc::ptr_eq(&self.shared, &other.shared) @@ -870,21 +870,21 @@ impl Sender { /// use futures::FutureExt; /// use tokio::sync::broadcast; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx1) = broadcast::channel::(16); - /// let mut rx2 = tx.subscribe(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx1) = broadcast::channel::(16); + /// let mut rx2 = tx.subscribe(); /// - /// let _ = tx.send(10); + /// let _ = tx.send(10); /// - /// assert_eq!(rx1.recv().await.unwrap(), 10); - /// drop(rx1); - /// assert!(tx.closed().now_or_never().is_none()); + /// assert_eq!(rx1.recv().await.unwrap(), 10); + /// drop(rx1); + /// assert!(tx.closed().now_or_never().is_none()); /// - /// assert_eq!(rx2.recv().await.unwrap(), 10); - /// drop(rx2); - /// assert!(tx.closed().now_or_never().is_some()); - /// } + /// assert_eq!(rx2.recv().await.unwrap(), 10); + /// drop(rx2); + /// assert!(tx.closed().now_or_never().is_some()); + /// # } /// ``` pub async fn closed(&self) { loop { @@ -1148,19 +1148,19 @@ impl Receiver { /// ``` /// use tokio::sync::broadcast; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx1) = broadcast::channel(16); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx1) = broadcast::channel(16); /// - /// tx.send(10).unwrap(); - /// tx.send(20).unwrap(); + /// tx.send(10).unwrap(); + /// tx.send(20).unwrap(); /// - /// assert_eq!(rx1.len(), 2); - /// assert_eq!(rx1.recv().await.unwrap(), 10); - /// assert_eq!(rx1.len(), 1); - /// assert_eq!(rx1.recv().await.unwrap(), 20); - /// assert_eq!(rx1.len(), 0); - /// } + /// assert_eq!(rx1.len(), 2); + /// assert_eq!(rx1.recv().await.unwrap(), 10); + /// assert_eq!(rx1.len(), 1); + /// assert_eq!(rx1.recv().await.unwrap(), 20); + /// assert_eq!(rx1.len(), 0); + /// # } /// ``` pub fn len(&self) -> usize { let next_send_pos = self.shared.tail.lock().pos; @@ -1177,20 +1177,20 @@ impl Receiver { /// ``` /// use tokio::sync::broadcast; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx1) = broadcast::channel(16); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx1) = broadcast::channel(16); /// - /// assert!(rx1.is_empty()); + /// assert!(rx1.is_empty()); /// - /// tx.send(10).unwrap(); - /// tx.send(20).unwrap(); + /// tx.send(10).unwrap(); + /// tx.send(20).unwrap(); /// - /// assert!(!rx1.is_empty()); - /// assert_eq!(rx1.recv().await.unwrap(), 10); - /// assert_eq!(rx1.recv().await.unwrap(), 20); - /// assert!(rx1.is_empty()); - /// } + /// assert!(!rx1.is_empty()); + /// assert_eq!(rx1.recv().await.unwrap(), 10); + /// assert_eq!(rx1.recv().await.unwrap(), 20); + /// assert!(rx1.is_empty()); + /// # } /// ``` pub fn is_empty(&self) -> bool { self.len() == 0 @@ -1203,17 +1203,17 @@ impl Receiver { /// ``` /// use tokio::sync::broadcast; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, rx) = broadcast::channel::<()>(16); - /// let rx2 = tx.subscribe(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, rx) = broadcast::channel::<()>(16); + /// let rx2 = tx.subscribe(); /// - /// assert!(rx.same_channel(&rx2)); + /// assert!(rx.same_channel(&rx2)); /// - /// let (_tx3, rx3) = broadcast::channel::<()>(16); + /// let (_tx3, rx3) = broadcast::channel::<()>(16); /// - /// assert!(!rx3.same_channel(&rx2)); - /// } + /// assert!(!rx3.same_channel(&rx2)); + /// # } /// ``` pub fn same_channel(&self, other: &Self) -> bool { Arc::ptr_eq(&self.shared, &other.shared) @@ -1348,15 +1348,15 @@ impl Receiver { /// ``` /// use tokio::sync::broadcast; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, rx) = broadcast::channel::<()>(10); - /// assert!(!rx.is_closed()); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, rx) = broadcast::channel::<()>(10); + /// assert!(!rx.is_closed()); /// - /// drop(tx); + /// drop(tx); /// - /// assert!(rx.is_closed()); - /// } + /// assert!(rx.is_closed()); + /// # } /// ``` pub fn is_closed(&self) -> bool { // Channel is closed when there are no strong senders left active @@ -1376,17 +1376,17 @@ impl Receiver { /// ``` /// use tokio::sync::broadcast; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = broadcast::channel(2); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = broadcast::channel(2); /// - /// tx.send(1).unwrap(); - /// let mut rx2 = rx.resubscribe(); - /// tx.send(2).unwrap(); + /// tx.send(1).unwrap(); + /// let mut rx2 = rx.resubscribe(); + /// tx.send(2).unwrap(); /// - /// assert_eq!(rx2.recv().await.unwrap(), 2); - /// assert_eq!(rx.recv().await.unwrap(), 1); - /// } + /// assert_eq!(rx2.recv().await.unwrap(), 2); + /// assert_eq!(rx.recv().await.unwrap(), 1); + /// # } /// ``` pub fn resubscribe(&self) -> Self { let shared = self.shared.clone(); @@ -1422,24 +1422,24 @@ impl Receiver { /// ``` /// use tokio::sync::broadcast; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx1) = broadcast::channel(16); - /// let mut rx2 = tx.subscribe(); + /// # #[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!(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); - /// }); + /// 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(); - /// } + /// tx.send(10).unwrap(); + /// tx.send(20).unwrap(); + /// # } /// ``` /// /// Handling lag @@ -1447,22 +1447,22 @@ impl Receiver { /// ``` /// use tokio::sync::broadcast; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = broadcast::channel(2); + /// # #[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(); + /// tx.send(10).unwrap(); + /// tx.send(20).unwrap(); + /// tx.send(30).unwrap(); /// - /// // The receiver lagged behind - /// assert!(rx.recv().await.is_err()); + /// // The receiver lagged behind + /// assert!(rx.recv().await.is_err()); /// - /// // At this point, we can abort or continue with lost messages + /// // 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()); - /// } + /// assert_eq!(20, rx.recv().await.unwrap()); + /// assert_eq!(30, rx.recv().await.unwrap()); + /// # } /// ``` pub async fn recv(&mut self) -> Result { cooperative(Recv::new(self)).await @@ -1496,17 +1496,17 @@ impl Receiver { /// ``` /// use tokio::sync::broadcast; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = broadcast::channel(16); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = broadcast::channel(16); /// - /// assert!(rx.try_recv().is_err()); + /// assert!(rx.try_recv().is_err()); /// - /// tx.send(10).unwrap(); + /// tx.send(10).unwrap(); /// - /// let value = rx.try_recv().unwrap(); - /// assert_eq!(10, value); - /// } + /// let value = rx.try_recv().unwrap(); + /// assert_eq!(10, value); + /// # } /// ``` pub fn try_recv(&mut self) -> Result { let guard = self.recv_ref(None)?; @@ -1522,6 +1522,8 @@ impl Receiver { /// /// # Examples /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use std::thread; /// use tokio::sync::broadcast; /// @@ -1536,6 +1538,7 @@ impl Receiver { /// let _ = tx.send(10); /// sync_code.join().unwrap(); /// } + /// # } /// ``` pub fn blocking_recv(&mut self) -> Result { crate::future::block_on(self.recv()) diff --git a/tokio/src/sync/mod.rs b/tokio/src/sync/mod.rs index d6d17c3f..52bf6509 100644 --- a/tokio/src/sync/mod.rs +++ b/tokio/src/sync/mod.rs @@ -42,20 +42,20 @@ //! "represents the result of the computation".to_string() //! } //! -//! #[tokio::main] -//! async fn main() { -//! let (tx, rx) = oneshot::channel(); +//! # #[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(); -//! }); +//! tokio::spawn(async move { +//! let res = some_computation().await; +//! tx.send(res).unwrap(); +//! }); //! -//! // Do other work while the computation is happening in the background +//! // Do other work while the computation is happening in the background //! -//! // Wait for the computation result -//! let res = rx.await.unwrap(); -//! } +//! // Wait for the computation result +//! let res = rx.await.unwrap(); +//! # } //! ``` //! //! Note, if the task produces a computation result as its final @@ -72,17 +72,17 @@ //! "the result of the computation".to_string() //! } //! -//! #[tokio::main] -//! async fn main() { -//! let join_handle = tokio::spawn(async move { -//! some_computation().await -//! }); +//! # #[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 +//! // Do other work while the computation is happening in the background //! -//! // Wait for the computation result -//! let res = join_handle.await.unwrap(); -//! } +//! // Wait for the computation result +//! let res = join_handle.await.unwrap(); +//! # } //! ``` //! //! [`JoinHandle`]: crate::task::JoinHandle @@ -107,21 +107,21 @@ //! format!("the result of computation {}", input) //! } //! -//! #[tokio::main] -//! 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(); -//! } -//! }); +//! # #[tokio::main(flavor = "current_thread")] +//! # async fn main() { +//! let (tx, mut rx) = mpsc::channel(100); //! -//! while let Some(res) = rx.recv().await { -//! println!("got = {}", res); +//! 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 @@ -141,6 +141,8 @@ //! passing. //! //! ```no_run +//! # #[cfg(not(target_family = "wasm"))] +//! # { //! use tokio::io::{self, AsyncWriteExt}; //! use tokio::net::TcpStream; //! use tokio::sync::mpsc; @@ -172,6 +174,7 @@ //! //! Ok(()) //! } +//! # } //! ``` //! //! The [`mpsc`] and [`oneshot`] channels can be combined to provide a request / @@ -193,46 +196,46 @@ //! // Other commands can be added here //! } //! -//! #[tokio::main] -//! async fn main() { -//! let (cmd_tx, mut cmd_rx) = mpsc::channel::<(Command, oneshot::Sender)>(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(); -//! } +//! # #[tokio::main(flavor = "current_thread")] +//! # async fn main() { +//! let (cmd_tx, mut cmd_rx) = mpsc::channel::<(Command, oneshot::Sender)>(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![]; +//! let mut join_handles = vec![]; //! -//! // Spawn tasks that will send the increment command. -//! for _ in 0..10 { -//! let cmd_tx = cmd_tx.clone(); +//! // 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(); +//! 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(); +//! cmd_tx.send((Increment, resp_tx)).await.ok().unwrap(); +//! let res = resp_rx.await.unwrap(); //! -//! println!("previous value = {}", res); -//! })); -//! } +//! println!("previous value = {}", res); +//! })); +//! } //! -//! // Wait for all tasks to complete -//! for join_handle in join_handles.drain(..) { -//! join_handle.await.unwrap(); -//! } +//! // Wait for all tasks to complete +//! for join_handle in join_handles.drain(..) { +//! join_handle.await.unwrap(); //! } +//! # } //! ``` //! //! ## `broadcast` channel @@ -254,24 +257,24 @@ //! ``` //! use tokio::sync::broadcast; //! -//! #[tokio::main] -//! async fn main() { -//! let (tx, mut rx1) = broadcast::channel(16); -//! let mut rx2 = tx.subscribe(); +//! # #[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!(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); -//! }); +//! 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(); -//! } +//! tx.send(10).unwrap(); +//! tx.send(20).unwrap(); +//! # } //! ``` //! //! [`broadcast` channel]: crate::sync::broadcast @@ -315,92 +318,92 @@ //! // Do something here //! } //! -//! #[tokio::main] -//! async fn main() { -//! // Load initial configuration value -//! let mut config = Config::load_from_file().await.unwrap(); +//! # #[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()); +//! // 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; +//! // 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(); +//! // 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; -//! } +//! // 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(); //! -//! 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 -//! } +//! // 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); -//! } +//! handles.push(handle); +//! } //! -//! for handle in handles.drain(..) { -//! handle.await.unwrap(); -//! } +//! for handle in handles.drain(..) { +//! handle.await.unwrap(); //! } +//! # } //! ``` //! //! [`watch` channel]: mod@crate::sync::watch diff --git a/tokio/src/sync/mpsc/bounded.rs b/tokio/src/sync/mpsc/bounded.rs index 06eeffc3..2bbffcec 100644 --- a/tokio/src/sync/mpsc/bounded.rs +++ b/tokio/src/sync/mpsc/bounded.rs @@ -40,18 +40,18 @@ pub struct Sender { /// ``` /// use tokio::sync::mpsc::channel; /// -/// #[tokio::main] -/// async fn main() { -/// let (tx, _rx) = channel::(15); -/// let tx_weak = tx.downgrade(); +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// let (tx, _rx) = channel::(15); +/// let tx_weak = tx.downgrade(); /// -/// // Upgrading will succeed because `tx` still exists. -/// assert!(tx_weak.upgrade().is_some()); +/// // 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()); -/// } +/// // If we drop `tx`, then it will fail. +/// drop(tx); +/// assert!(tx_weak.clone().upgrade().is_none()); +/// # } /// ``` pub struct WeakSender { chan: Arc>, @@ -134,23 +134,23 @@ pub struct Receiver { /// ```rust /// use tokio::sync::mpsc; /// -/// #[tokio::main] -/// async fn main() { -/// let (tx, mut rx) = mpsc::channel(100); +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// let (tx, mut rx) = mpsc::channel(100); /// -/// tokio::spawn(async move { -/// for i in 0..10 { -/// if let Err(_) = tx.send(i).await { -/// println!("receiver dropped"); -/// return; -/// } +/// tokio::spawn(async move { +/// for i in 0..10 { +/// if let Err(_) = tx.send(i).await { +/// println!("receiver dropped"); +/// return; /// } -/// }); -/// -/// while let Some(i) = rx.recv().await { -/// println!("got = {}", i); /// } +/// }); +/// +/// while let Some(i) = rx.recv().await { +/// println!("got = {}", i); /// } +/// # } /// ``` #[track_caller] pub fn channel(buffer: usize) -> (Sender, Receiver) { @@ -208,17 +208,17 @@ impl Receiver { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = mpsc::channel(100); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = mpsc::channel(100); /// - /// tokio::spawn(async move { - /// tx.send("hello").await.unwrap(); - /// }); + /// tokio::spawn(async move { + /// tx.send("hello").await.unwrap(); + /// }); /// - /// assert_eq!(Some("hello"), rx.recv().await); - /// assert_eq!(None, rx.recv().await); - /// } + /// assert_eq!(Some("hello"), rx.recv().await); + /// assert_eq!(None, rx.recv().await); + /// # } /// ``` /// /// Values are buffered: @@ -226,16 +226,16 @@ impl Receiver { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = mpsc::channel(100); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = mpsc::channel(100); /// - /// tx.send("hello").await.unwrap(); - /// tx.send("world").await.unwrap(); + /// tx.send("hello").await.unwrap(); + /// tx.send("world").await.unwrap(); /// - /// assert_eq!(Some("hello"), rx.recv().await); - /// assert_eq!(Some("world"), rx.recv().await); - /// } + /// assert_eq!(Some("hello"), rx.recv().await); + /// assert_eq!(Some("world"), rx.recv().await); + /// # } /// ``` pub async fn recv(&mut self) -> Option { use std::future::poll_fn; @@ -278,40 +278,40 @@ impl Receiver { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let mut buffer: Vec<&str> = Vec::with_capacity(2); - /// let limit = 2; - /// let (tx, mut rx) = mpsc::channel(100); - /// let tx2 = tx.clone(); - /// tx2.send("first").await.unwrap(); - /// tx2.send("second").await.unwrap(); - /// tx2.send("third").await.unwrap(); - /// - /// // Call `recv_many` to receive up to `limit` (2) values. - /// assert_eq!(2, rx.recv_many(&mut buffer, limit).await); - /// assert_eq!(vec!["first", "second"], buffer); - /// - /// // If the buffer is full, the next call to `recv_many` - /// // reserves additional capacity. - /// assert_eq!(1, rx.recv_many(&mut buffer, 1).await); - /// - /// tokio::spawn(async move { - /// tx.send("fourth").await.unwrap(); - /// }); - /// - /// // 'tx' is dropped, but `recv_many` - /// // is guaranteed not to return 0 as the channel - /// // is not yet closed. - /// assert_eq!(1, rx.recv_many(&mut buffer, 1).await); - /// assert_eq!(vec!["first", "second", "third", "fourth"], buffer); - /// - /// // Once the last sender is dropped, the channel is - /// // closed and `recv_many` returns 0, capacity unchanged. - /// drop(tx2); - /// assert_eq!(0, rx.recv_many(&mut buffer, limit).await); - /// assert_eq!(vec!["first", "second", "third", "fourth"], buffer); - /// } + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let mut buffer: Vec<&str> = Vec::with_capacity(2); + /// let limit = 2; + /// let (tx, mut rx) = mpsc::channel(100); + /// let tx2 = tx.clone(); + /// tx2.send("first").await.unwrap(); + /// tx2.send("second").await.unwrap(); + /// tx2.send("third").await.unwrap(); + /// + /// // Call `recv_many` to receive up to `limit` (2) values. + /// assert_eq!(2, rx.recv_many(&mut buffer, limit).await); + /// assert_eq!(vec!["first", "second"], buffer); + /// + /// // If the buffer is full, the next call to `recv_many` + /// // reserves additional capacity. + /// assert_eq!(1, rx.recv_many(&mut buffer, 1).await); + /// + /// tokio::spawn(async move { + /// tx.send("fourth").await.unwrap(); + /// }); + /// + /// // 'tx' is dropped, but `recv_many` + /// // is guaranteed not to return 0 as the channel + /// // is not yet closed. + /// assert_eq!(1, rx.recv_many(&mut buffer, 1).await); + /// assert_eq!(vec!["first", "second", "third", "fourth"], buffer); + /// + /// // Once the last sender is dropped, the channel is + /// // closed and `recv_many` returns 0, capacity unchanged. + /// drop(tx2); + /// assert_eq!(0, rx.recv_many(&mut buffer, limit).await); + /// assert_eq!(vec!["first", "second", "third", "fourth"], buffer); + /// # } /// ``` pub async fn recv_many(&mut self, buffer: &mut Vec, limit: usize) -> usize { use std::future::poll_fn; @@ -341,22 +341,22 @@ impl Receiver { /// use tokio::sync::mpsc; /// use tokio::sync::mpsc::error::TryRecvError; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = mpsc::channel(100); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = mpsc::channel(100); /// - /// tx.send("hello").await.unwrap(); + /// tx.send("hello").await.unwrap(); /// - /// assert_eq!(Ok("hello"), rx.try_recv()); - /// assert_eq!(Err(TryRecvError::Empty), rx.try_recv()); + /// assert_eq!(Ok("hello"), rx.try_recv()); + /// assert_eq!(Err(TryRecvError::Empty), rx.try_recv()); /// - /// tx.send("hello").await.unwrap(); - /// // Drop the last sender, closing the channel. - /// drop(tx); + /// tx.send("hello").await.unwrap(); + /// // Drop the last sender, closing the channel. + /// drop(tx); /// - /// assert_eq!(Ok("hello"), rx.try_recv()); - /// assert_eq!(Err(TryRecvError::Disconnected), rx.try_recv()); - /// } + /// assert_eq!(Ok("hello"), rx.try_recv()); + /// assert_eq!(Err(TryRecvError::Disconnected), rx.try_recv()); + /// # } /// ``` pub fn try_recv(&mut self) -> Result { self.chan.try_recv() @@ -393,6 +393,8 @@ impl Receiver { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use std::thread; /// use tokio::runtime::Runtime; /// use tokio::sync::mpsc; @@ -411,6 +413,7 @@ impl Receiver { /// }); /// sync_code.join().unwrap() /// } + /// # } /// ``` #[track_caller] #[cfg(feature = "sync")] @@ -448,26 +451,26 @@ impl Receiver { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = mpsc::channel(20); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = mpsc::channel(20); /// - /// tokio::spawn(async move { - /// let mut i = 0; - /// while let Ok(permit) = tx.reserve().await { - /// permit.send(i); - /// i += 1; - /// } - /// }); - /// - /// rx.close(); - /// - /// while let Some(msg) = rx.recv().await { - /// println!("got {}", msg); + /// tokio::spawn(async move { + /// let mut i = 0; + /// while let Ok(permit) = tx.reserve().await { + /// permit.send(i); + /// i += 1; /// } + /// }); /// - /// // Channel closed and no messages are lost. + /// rx.close(); + /// + /// while let Some(msg) = rx.recv().await { + /// println!("got {}", msg); /// } + /// + /// // Channel closed and no messages are lost. + /// # } /// ``` pub fn close(&mut self) { self.chan.close(); @@ -485,15 +488,15 @@ impl Receiver { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (_tx, mut rx) = mpsc::channel::<()>(10); - /// assert!(!rx.is_closed()); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (_tx, mut rx) = mpsc::channel::<()>(10); + /// assert!(!rx.is_closed()); /// - /// rx.close(); + /// rx.close(); /// - /// assert!(rx.is_closed()); - /// } + /// assert!(rx.is_closed()); + /// # } /// ``` pub fn is_closed(&self) -> bool { self.chan.is_closed() @@ -507,14 +510,14 @@ impl Receiver { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, rx) = mpsc::channel(10); - /// assert!(rx.is_empty()); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, rx) = mpsc::channel(10); + /// assert!(rx.is_empty()); /// - /// tx.send(0).await.unwrap(); - /// assert!(!rx.is_empty()); - /// } + /// tx.send(0).await.unwrap(); + /// assert!(!rx.is_empty()); + /// # } /// /// ``` pub fn is_empty(&self) -> bool { @@ -527,14 +530,14 @@ impl Receiver { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, rx) = mpsc::channel(10); - /// assert_eq!(0, rx.len()); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, rx) = mpsc::channel(10); + /// assert_eq!(0, rx.len()); /// - /// tx.send(0).await.unwrap(); - /// assert_eq!(1, rx.len()); - /// } + /// tx.send(0).await.unwrap(); + /// assert_eq!(1, rx.len()); + /// # } /// ``` pub fn len(&self) -> usize { self.chan.len() @@ -552,33 +555,33 @@ impl Receiver { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = mpsc::channel::<()>(5); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = mpsc::channel::<()>(5); /// - /// assert_eq!(rx.capacity(), 5); + /// assert_eq!(rx.capacity(), 5); /// - /// // Making a reservation drops the capacity by one. - /// let permit = tx.reserve().await.unwrap(); - /// assert_eq!(rx.capacity(), 4); - /// assert_eq!(rx.len(), 0); + /// // Making a reservation drops the capacity by one. + /// let permit = tx.reserve().await.unwrap(); + /// assert_eq!(rx.capacity(), 4); + /// assert_eq!(rx.len(), 0); /// - /// // Sending and receiving a value increases the capacity by one. - /// permit.send(()); - /// assert_eq!(rx.len(), 1); - /// rx.recv().await.unwrap(); - /// assert_eq!(rx.capacity(), 5); + /// // Sending and receiving a value increases the capacity by one. + /// permit.send(()); + /// assert_eq!(rx.len(), 1); + /// rx.recv().await.unwrap(); + /// assert_eq!(rx.capacity(), 5); /// - /// // Directly sending a message drops the capacity by one. - /// tx.send(()).await.unwrap(); - /// assert_eq!(rx.capacity(), 4); - /// assert_eq!(rx.len(), 1); + /// // Directly sending a message drops the capacity by one. + /// tx.send(()).await.unwrap(); + /// assert_eq!(rx.capacity(), 4); + /// assert_eq!(rx.len(), 1); /// - /// // Receiving the message increases the capacity by one. - /// rx.recv().await.unwrap(); - /// assert_eq!(rx.capacity(), 5); - /// assert_eq!(rx.len(), 0); - /// } + /// // Receiving the message increases the capacity by one. + /// rx.recv().await.unwrap(); + /// assert_eq!(rx.capacity(), 5); + /// assert_eq!(rx.len(), 0); + /// # } /// ``` /// [`capacity`]: Receiver::capacity /// [`max_capacity`]: Receiver::max_capacity @@ -599,20 +602,20 @@ impl Receiver { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, rx) = mpsc::channel::<()>(5); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, rx) = mpsc::channel::<()>(5); /// - /// // both max capacity and capacity are the same at first - /// assert_eq!(rx.max_capacity(), 5); - /// assert_eq!(rx.capacity(), 5); + /// // both max capacity and capacity are the same at first + /// assert_eq!(rx.max_capacity(), 5); + /// assert_eq!(rx.capacity(), 5); /// - /// // Making a reservation doesn't change the max capacity. - /// let permit = tx.reserve().await.unwrap(); - /// assert_eq!(rx.max_capacity(), 5); - /// // but drops the capacity by one - /// assert_eq!(rx.capacity(), 4); - /// } + /// // Making a reservation doesn't change the max capacity. + /// let permit = tx.reserve().await.unwrap(); + /// assert_eq!(rx.max_capacity(), 5); + /// // but drops the capacity by one + /// assert_eq!(rx.capacity(), 4); + /// # } /// ``` /// [`capacity`]: Receiver::capacity /// [`max_capacity`]: Receiver::max_capacity @@ -693,25 +696,25 @@ impl Receiver { /// } /// } /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, rx) = mpsc::channel(32); - /// let mut buffer = Vec::new(); - /// - /// let my_receiver_future = MyReceiverFuture { - /// receiver: rx, - /// buffer: &mut buffer, - /// limit: 3, - /// }; + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, rx) = mpsc::channel(32); + /// let mut buffer = Vec::new(); /// - /// for i in 0..10 { - /// tx.send(i).await.unwrap(); - /// } + /// let my_receiver_future = MyReceiverFuture { + /// receiver: rx, + /// buffer: &mut buffer, + /// limit: 3, + /// }; /// - /// let count = my_receiver_future.await; - /// assert_eq!(count, 3); - /// assert_eq!(buffer, vec![0,1,2]) + /// for i in 0..10 { + /// tx.send(i).await.unwrap(); /// } + /// + /// let count = my_receiver_future.await; + /// assert_eq!(count, 3); + /// assert_eq!(buffer, vec![0,1,2]) + /// # } /// ``` pub fn poll_recv_many( &mut self, @@ -789,23 +792,23 @@ impl Sender { /// ```rust /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = mpsc::channel(1); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = mpsc::channel(1); /// - /// tokio::spawn(async move { - /// for i in 0..10 { - /// if let Err(_) = tx.send(i).await { - /// println!("receiver dropped"); - /// return; - /// } + /// tokio::spawn(async move { + /// for i in 0..10 { + /// if let Err(_) = tx.send(i).await { + /// println!("receiver dropped"); + /// return; /// } - /// }); - /// - /// while let Some(i) = rx.recv().await { - /// println!("got = {}", i); /// } + /// }); + /// + /// while let Some(i) = rx.recv().await { + /// println!("got = {}", i); /// } + /// # } /// ``` pub async fn send(&self, value: T) -> Result<(), SendError> { match self.reserve().await { @@ -832,26 +835,26 @@ impl Sender { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx1, rx) = mpsc::channel::<()>(1); - /// let tx2 = tx1.clone(); - /// let tx3 = tx1.clone(); - /// let tx4 = tx1.clone(); - /// let tx5 = tx1.clone(); - /// tokio::spawn(async move { - /// drop(rx); - /// }); - /// - /// futures::join!( - /// tx1.closed(), - /// tx2.closed(), - /// tx3.closed(), - /// tx4.closed(), - /// tx5.closed() - /// ); - /// println!("Receiver dropped"); - /// } + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx1, rx) = mpsc::channel::<()>(1); + /// let tx2 = tx1.clone(); + /// let tx3 = tx1.clone(); + /// let tx4 = tx1.clone(); + /// let tx5 = tx1.clone(); + /// tokio::spawn(async move { + /// drop(rx); + /// }); + /// + /// futures::join!( + /// tx1.closed(), + /// tx2.closed(), + /// tx3.closed(), + /// tx4.closed(), + /// tx5.closed() + /// ); + /// println!("Receiver dropped"); + /// # } /// ``` pub async fn closed(&self) { self.chan.closed().await; @@ -883,37 +886,37 @@ impl Sender { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// // Create a channel with buffer size 1 - /// let (tx1, mut rx) = mpsc::channel(1); - /// let tx2 = tx1.clone(); - /// - /// tokio::spawn(async move { - /// tx1.send(1).await.unwrap(); - /// tx1.send(2).await.unwrap(); - /// // task waits until the receiver receives a value. - /// }); - /// - /// tokio::spawn(async move { - /// // This will return an error and send - /// // no message if the buffer is full - /// let _ = tx2.try_send(3); - /// }); - /// - /// let mut msg; - /// msg = rx.recv().await.unwrap(); - /// println!("message {} received", msg); - /// - /// msg = rx.recv().await.unwrap(); - /// println!("message {} received", msg); - /// - /// // Third message may have never been sent - /// match rx.recv().await { - /// Some(msg) => println!("message {} received", msg), - /// None => println!("the third message was never sent"), - /// } + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// // Create a channel with buffer size 1 + /// let (tx1, mut rx) = mpsc::channel(1); + /// let tx2 = tx1.clone(); + /// + /// tokio::spawn(async move { + /// tx1.send(1).await.unwrap(); + /// tx1.send(2).await.unwrap(); + /// // task waits until the receiver receives a value. + /// }); + /// + /// tokio::spawn(async move { + /// // This will return an error and send + /// // no message if the buffer is full + /// let _ = tx2.try_send(3); + /// }); + /// + /// let mut msg; + /// msg = rx.recv().await.unwrap(); + /// println!("message {} received", msg); + /// + /// msg = rx.recv().await.unwrap(); + /// println!("message {} received", msg); + /// + /// // Third message may have never been sent + /// match rx.recv().await { + /// Some(msg) => println!("message {} received", msg), + /// None => println!("the third message was never sent"), /// } + /// # } /// ``` pub fn try_send(&self, message: T) -> Result<(), TrySendError> { match self.chan.semaphore().semaphore.try_acquire(1) { @@ -958,24 +961,24 @@ impl Sender { /// use tokio::sync::mpsc; /// use tokio::time::{sleep, Duration}; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = mpsc::channel(1); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = mpsc::channel(1); /// - /// tokio::spawn(async move { - /// for i in 0..10 { - /// if let Err(e) = tx.send_timeout(i, Duration::from_millis(100)).await { - /// println!("send error: #{:?}", e); - /// return; - /// } + /// tokio::spawn(async move { + /// for i in 0..10 { + /// if let Err(e) = tx.send_timeout(i, Duration::from_millis(100)).await { + /// println!("send error: #{:?}", e); + /// return; /// } - /// }); - /// - /// while let Some(i) = rx.recv().await { - /// println!("got = {}", i); - /// sleep(Duration::from_millis(200)).await; /// } + /// }); + /// + /// while let Some(i) = rx.recv().await { + /// println!("got = {}", i); + /// sleep(Duration::from_millis(200)).await; /// } + /// # } /// ``` #[cfg(feature = "time")] #[cfg_attr(docsrs, doc(cfg(feature = "time")))] @@ -1014,6 +1017,8 @@ impl Sender { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use std::thread; /// use tokio::runtime::Runtime; /// use tokio::sync::mpsc; @@ -1030,6 +1035,7 @@ impl Sender { /// }); /// sync_code.join().unwrap() /// } + /// # } /// ``` #[track_caller] #[cfg(feature = "sync")] @@ -1086,23 +1092,23 @@ impl Sender { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = mpsc::channel(1); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = mpsc::channel(1); /// - /// // Reserve capacity - /// let permit = tx.reserve().await.unwrap(); + /// // Reserve capacity + /// let permit = tx.reserve().await.unwrap(); /// - /// // Trying to send directly on the `tx` will fail due to no - /// // available capacity. - /// assert!(tx.try_send(123).is_err()); + /// // Trying to send directly on the `tx` will fail due to no + /// // available capacity. + /// assert!(tx.try_send(123).is_err()); /// - /// // Sending on the permit succeeds - /// permit.send(456); + /// // Sending on the permit succeeds + /// permit.send(456); /// - /// // The value sent on the permit is received - /// assert_eq!(rx.recv().await.unwrap(), 456); - /// } + /// // The value sent on the permit is received + /// assert_eq!(rx.recv().await.unwrap(), 456); + /// # } /// ``` pub async fn reserve(&self) -> Result, SendError<()>> { self.reserve_inner(1).await?; @@ -1142,28 +1148,28 @@ impl Sender { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = mpsc::channel(2); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = mpsc::channel(2); /// - /// // Reserve capacity - /// let mut permit = tx.reserve_many(2).await.unwrap(); + /// // Reserve capacity + /// let mut permit = tx.reserve_many(2).await.unwrap(); /// - /// // Trying to send directly on the `tx` will fail due to no - /// // available capacity. - /// assert!(tx.try_send(123).is_err()); + /// // Trying to send directly on the `tx` will fail due to no + /// // available capacity. + /// assert!(tx.try_send(123).is_err()); /// - /// // Sending with the permit iterator succeeds - /// permit.next().unwrap().send(456); - /// permit.next().unwrap().send(457); + /// // Sending with the permit iterator succeeds + /// permit.next().unwrap().send(456); + /// permit.next().unwrap().send(457); /// - /// // The iterator should now be exhausted - /// assert!(permit.next().is_none()); + /// // The iterator should now be exhausted + /// assert!(permit.next().is_none()); /// - /// // The value sent on the permit is received - /// assert_eq!(rx.recv().await.unwrap(), 456); - /// assert_eq!(rx.recv().await.unwrap(), 457); - /// } + /// // The value sent on the permit is received + /// assert_eq!(rx.recv().await.unwrap(), 456); + /// assert_eq!(rx.recv().await.unwrap(), 457); + /// # } /// ``` pub async fn reserve_many(&self, n: usize) -> Result, SendError<()>> { self.reserve_inner(n).await?; @@ -1205,23 +1211,23 @@ impl Sender { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = mpsc::channel(1); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = mpsc::channel(1); /// - /// // Reserve capacity, moving the sender. - /// let permit = tx.reserve_owned().await.unwrap(); + /// // Reserve capacity, moving the sender. + /// let permit = tx.reserve_owned().await.unwrap(); /// - /// // Send a message, consuming the permit and returning - /// // the moved sender. - /// let tx = permit.send(123); + /// // Send a message, consuming the permit and returning + /// // the moved sender. + /// let tx = permit.send(123); /// - /// // The value sent on the permit is received. - /// assert_eq!(rx.recv().await.unwrap(), 123); + /// // The value sent on the permit is received. + /// assert_eq!(rx.recv().await.unwrap(), 123); /// - /// // The sender can now be used again. - /// tx.send(456).await.unwrap(); - /// } + /// // The sender can now be used again. + /// tx.send(456).await.unwrap(); + /// # } /// ``` /// /// When multiple [`OwnedPermit`]s are needed, or the sender cannot be moved @@ -1230,23 +1236,23 @@ impl Sender { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = mpsc::channel(1); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = mpsc::channel(1); /// - /// // Clone the sender and reserve capacity. - /// let permit = tx.clone().reserve_owned().await.unwrap(); + /// // Clone the sender and reserve capacity. + /// let permit = tx.clone().reserve_owned().await.unwrap(); /// - /// // Trying to send directly on the `tx` will fail due to no - /// // available capacity. - /// assert!(tx.try_send(123).is_err()); + /// // Trying to send directly on the `tx` will fail due to no + /// // available capacity. + /// assert!(tx.try_send(123).is_err()); /// - /// // Sending on the permit succeeds. - /// permit.send(456); + /// // Sending on the permit succeeds. + /// permit.send(456); /// - /// // The value sent on the permit is received - /// assert_eq!(rx.recv().await.unwrap(), 456); - /// } + /// // The value sent on the permit is received + /// assert_eq!(rx.recv().await.unwrap(), 456); + /// # } /// ``` /// /// [`Sender::reserve`]: Sender::reserve @@ -1292,28 +1298,28 @@ impl Sender { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = mpsc::channel(1); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = mpsc::channel(1); /// - /// // Reserve capacity - /// let permit = tx.try_reserve().unwrap(); + /// // Reserve capacity + /// let permit = tx.try_reserve().unwrap(); /// - /// // Trying to send directly on the `tx` will fail due to no - /// // available capacity. - /// assert!(tx.try_send(123).is_err()); + /// // Trying to send directly on the `tx` will fail due to no + /// // available capacity. + /// assert!(tx.try_send(123).is_err()); /// - /// // Trying to reserve an additional slot on the `tx` will - /// // fail because there is no capacity. - /// assert!(tx.try_reserve().is_err()); + /// // Trying to reserve an additional slot on the `tx` will + /// // fail because there is no capacity. + /// assert!(tx.try_reserve().is_err()); /// - /// // Sending on the permit succeeds - /// permit.send(456); + /// // Sending on the permit succeeds + /// permit.send(456); /// - /// // The value sent on the permit is received - /// assert_eq!(rx.recv().await.unwrap(), 456); + /// // The value sent on the permit is received + /// assert_eq!(rx.recv().await.unwrap(), 456); /// - /// } + /// # } /// ``` pub fn try_reserve(&self) -> Result, TrySendError<()>> { match self.chan.semaphore().semaphore.try_acquire(1) { @@ -1349,49 +1355,49 @@ impl Sender { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = mpsc::channel(2); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = mpsc::channel(2); /// - /// // Reserve capacity - /// let mut permit = tx.try_reserve_many(2).unwrap(); + /// // Reserve capacity + /// let mut permit = tx.try_reserve_many(2).unwrap(); /// - /// // Trying to send directly on the `tx` will fail due to no - /// // available capacity. - /// assert!(tx.try_send(123).is_err()); + /// // Trying to send directly on the `tx` will fail due to no + /// // available capacity. + /// assert!(tx.try_send(123).is_err()); /// - /// // Trying to reserve an additional slot on the `tx` will - /// // fail because there is no capacity. - /// assert!(tx.try_reserve().is_err()); + /// // Trying to reserve an additional slot on the `tx` will + /// // fail because there is no capacity. + /// assert!(tx.try_reserve().is_err()); /// - /// // Sending with the permit iterator succeeds - /// permit.next().unwrap().send(456); - /// permit.next().unwrap().send(457); + /// // Sending with the permit iterator succeeds + /// permit.next().unwrap().send(456); + /// permit.next().unwrap().send(457); /// - /// // The iterator should now be exhausted - /// assert!(permit.next().is_none()); + /// // The iterator should now be exhausted + /// assert!(permit.next().is_none()); /// - /// // The value sent on the permit is received - /// assert_eq!(rx.recv().await.unwrap(), 456); - /// assert_eq!(rx.recv().await.unwrap(), 457); + /// // The value sent on the permit is received + /// assert_eq!(rx.recv().await.unwrap(), 456); + /// assert_eq!(rx.recv().await.unwrap(), 457); /// - /// // Trying to call try_reserve_many with 0 will return an empty iterator - /// let mut permit = tx.try_reserve_many(0).unwrap(); - /// assert!(permit.next().is_none()); + /// // Trying to call try_reserve_many with 0 will return an empty iterator + /// let mut permit = tx.try_reserve_many(0).unwrap(); + /// assert!(permit.next().is_none()); /// - /// // Trying to call try_reserve_many with a number greater than the channel - /// // capacity will return an error - /// let permit = tx.try_reserve_many(3); - /// assert!(permit.is_err()); + /// // Trying to call try_reserve_many with a number greater than the channel + /// // capacity will return an error + /// let permit = tx.try_reserve_many(3); + /// assert!(permit.is_err()); /// - /// // Trying to call try_reserve_many on a closed channel will return an error - /// drop(rx); - /// let permit = tx.try_reserve_many(1); - /// assert!(permit.is_err()); + /// // Trying to call try_reserve_many on a closed channel will return an error + /// drop(rx); + /// let permit = tx.try_reserve_many(1); + /// assert!(permit.is_err()); /// - /// let permit = tx.try_reserve_many(0); - /// assert!(permit.is_err()); - /// } + /// let permit = tx.try_reserve_many(0); + /// assert!(permit.is_err()); + /// # } /// ``` pub fn try_reserve_many(&self, n: usize) -> Result, TrySendError<()>> { if n > self.max_capacity() { @@ -1442,28 +1448,28 @@ impl Sender { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = mpsc::channel(1); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = mpsc::channel(1); /// - /// // Reserve capacity - /// let permit = tx.clone().try_reserve_owned().unwrap(); + /// // Reserve capacity + /// let permit = tx.clone().try_reserve_owned().unwrap(); /// - /// // Trying to send directly on the `tx` will fail due to no - /// // available capacity. - /// assert!(tx.try_send(123).is_err()); + /// // Trying to send directly on the `tx` will fail due to no + /// // available capacity. + /// assert!(tx.try_send(123).is_err()); /// - /// // Trying to reserve an additional slot on the `tx` will - /// // fail because there is no capacity. - /// assert!(tx.try_reserve().is_err()); + /// // Trying to reserve an additional slot on the `tx` will + /// // fail because there is no capacity. + /// assert!(tx.try_reserve().is_err()); /// - /// // Sending on the permit succeeds - /// permit.send(456); + /// // Sending on the permit succeeds + /// permit.send(456); /// - /// // The value sent on the permit is received - /// assert_eq!(rx.recv().await.unwrap(), 456); + /// // The value sent on the permit is received + /// assert_eq!(rx.recv().await.unwrap(), 456); /// - /// } + /// # } /// ``` pub fn try_reserve_owned(self) -> Result, TrySendError> { match self.chan.semaphore().semaphore.try_acquire(1) { @@ -1505,21 +1511,21 @@ impl Sender { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = mpsc::channel::<()>(5); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = mpsc::channel::<()>(5); /// - /// assert_eq!(tx.capacity(), 5); + /// assert_eq!(tx.capacity(), 5); /// - /// // Making a reservation drops the capacity by one. - /// let permit = tx.reserve().await.unwrap(); - /// assert_eq!(tx.capacity(), 4); + /// // Making a reservation drops the capacity by one. + /// let permit = tx.reserve().await.unwrap(); + /// assert_eq!(tx.capacity(), 4); /// - /// // Sending and receiving a value increases the capacity by one. - /// permit.send(()); - /// rx.recv().await.unwrap(); - /// assert_eq!(tx.capacity(), 5); - /// } + /// // Sending and receiving a value increases the capacity by one. + /// permit.send(()); + /// rx.recv().await.unwrap(); + /// assert_eq!(tx.capacity(), 5); + /// # } /// ``` /// /// [`send`]: Sender::send @@ -1554,20 +1560,20 @@ impl Sender { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, _rx) = mpsc::channel::<()>(5); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, _rx) = mpsc::channel::<()>(5); /// - /// // both max capacity and capacity are the same at first - /// assert_eq!(tx.max_capacity(), 5); - /// assert_eq!(tx.capacity(), 5); + /// // both max capacity and capacity are the same at first + /// assert_eq!(tx.max_capacity(), 5); + /// assert_eq!(tx.capacity(), 5); /// - /// // Making a reservation doesn't change the max capacity. - /// let permit = tx.reserve().await.unwrap(); - /// assert_eq!(tx.max_capacity(), 5); - /// // but drops the capacity by one - /// assert_eq!(tx.capacity(), 4); - /// } + /// // Making a reservation doesn't change the max capacity. + /// let permit = tx.reserve().await.unwrap(); + /// assert_eq!(tx.max_capacity(), 5); + /// // but drops the capacity by one + /// assert_eq!(tx.capacity(), 4); + /// # } /// ``` /// /// [`channel`]: channel @@ -1662,23 +1668,23 @@ impl Permit<'_, T> { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = mpsc::channel(1); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = mpsc::channel(1); /// - /// // Reserve capacity - /// let permit = tx.reserve().await.unwrap(); + /// // Reserve capacity + /// let permit = tx.reserve().await.unwrap(); /// - /// // Trying to send directly on the `tx` will fail due to no - /// // available capacity. - /// assert!(tx.try_send(123).is_err()); + /// // Trying to send directly on the `tx` will fail due to no + /// // available capacity. + /// assert!(tx.try_send(123).is_err()); /// - /// // Send a message on the permit - /// permit.send(456); + /// // Send a message on the permit + /// permit.send(456); /// - /// // The value sent on the permit is received - /// assert_eq!(rx.recv().await.unwrap(), 456); - /// } + /// // The value sent on the permit is received + /// assert_eq!(rx.recv().await.unwrap(), 456); + /// # } /// ``` pub fn send(self, value: T) { use std::mem; @@ -1787,22 +1793,22 @@ impl OwnedPermit { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = mpsc::channel(1); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = mpsc::channel(1); /// - /// // Reserve capacity - /// let permit = tx.reserve_owned().await.unwrap(); + /// // Reserve capacity + /// let permit = tx.reserve_owned().await.unwrap(); /// - /// // Send a message on the permit, returning the sender. - /// let tx = permit.send(456); + /// // Send a message on the permit, returning the sender. + /// let tx = permit.send(456); /// - /// // The value sent on the permit is received - /// assert_eq!(rx.recv().await.unwrap(), 456); + /// // The value sent on the permit is received + /// assert_eq!(rx.recv().await.unwrap(), 456); /// - /// // We may now reuse `tx` to send another message. - /// tx.send(789).await.unwrap(); - /// } + /// // We may now reuse `tx` to send another message. + /// tx.send(789).await.unwrap(); + /// # } /// ``` pub fn send(mut self, value: T) -> Sender { let chan = self.chan.take().unwrap_or_else(|| { @@ -1821,25 +1827,25 @@ impl OwnedPermit { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, rx) = mpsc::channel(1); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, rx) = mpsc::channel(1); /// - /// // Clone the sender and reserve capacity - /// let permit = tx.clone().reserve_owned().await.unwrap(); + /// // Clone the sender and reserve capacity + /// let permit = tx.clone().reserve_owned().await.unwrap(); /// - /// // Trying to send on the original `tx` will fail, since the `permit` - /// // has reserved all the available capacity. - /// assert!(tx.try_send(123).is_err()); + /// // Trying to send on the original `tx` will fail, since the `permit` + /// // has reserved all the available capacity. + /// assert!(tx.try_send(123).is_err()); /// - /// // Release the permit without sending a message, returning the clone - /// // of the sender. - /// let tx2 = permit.release(); + /// // Release the permit without sending a message, returning the clone + /// // of the sender. + /// let tx2 = permit.release(); /// - /// // We may now reuse `tx` to send another message. - /// tx.send(789).await.unwrap(); - /// # drop(rx); drop(tx2); - /// } + /// // We may now reuse `tx` to send another message. + /// tx.send(789).await.unwrap(); + /// # drop(rx); drop(tx2); + /// # } /// ``` /// /// [`Sender`]: Sender @@ -1862,19 +1868,19 @@ impl OwnedPermit { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, rx) = mpsc::channel::<()>(2); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, rx) = mpsc::channel::<()>(2); /// - /// let permit1 = tx.clone().reserve_owned().await.unwrap(); - /// let permit2 = tx.clone().reserve_owned().await.unwrap(); - /// assert!(permit1.same_channel(&permit2)); + /// let permit1 = tx.clone().reserve_owned().await.unwrap(); + /// let permit2 = tx.clone().reserve_owned().await.unwrap(); + /// assert!(permit1.same_channel(&permit2)); /// - /// let (tx2, rx2) = mpsc::channel::<()>(1); + /// let (tx2, rx2) = mpsc::channel::<()>(1); /// - /// let permit3 = tx2.clone().reserve_owned().await.unwrap(); - /// assert!(!permit3.same_channel(&permit2)); - /// } + /// let permit3 = tx2.clone().reserve_owned().await.unwrap(); + /// assert!(!permit3.same_channel(&permit2)); + /// # } /// ``` pub fn same_channel(&self, other: &Self) -> bool { self.chan @@ -1890,16 +1896,16 @@ impl OwnedPermit { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, rx) = mpsc::channel::<()>(1); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, rx) = mpsc::channel::<()>(1); /// - /// let permit = tx.clone().reserve_owned().await.unwrap(); - /// assert!(permit.same_channel_as_sender(&tx)); + /// let permit = tx.clone().reserve_owned().await.unwrap(); + /// assert!(permit.same_channel_as_sender(&tx)); /// - /// let (tx2, rx2) = mpsc::channel::<()>(1); - /// assert!(!permit.same_channel_as_sender(&tx2)); - /// } + /// let (tx2, rx2) = mpsc::channel::<()>(1); + /// assert!(!permit.same_channel_as_sender(&tx2)); + /// # } /// ``` pub fn same_channel_as_sender(&self, sender: &Sender) -> bool { self.chan diff --git a/tokio/src/sync/mpsc/unbounded.rs b/tokio/src/sync/mpsc/unbounded.rs index a9232dc9..add38672 100644 --- a/tokio/src/sync/mpsc/unbounded.rs +++ b/tokio/src/sync/mpsc/unbounded.rs @@ -29,18 +29,18 @@ pub struct UnboundedSender { /// ``` /// use tokio::sync::mpsc::unbounded_channel; /// -/// #[tokio::main] -/// async fn main() { -/// let (tx, _rx) = unbounded_channel::(); -/// let tx_weak = tx.downgrade(); +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// let (tx, _rx) = unbounded_channel::(); +/// let tx_weak = tx.downgrade(); /// -/// // Upgrading will succeed because `tx` still exists. -/// assert!(tx_weak.upgrade().is_some()); +/// // 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()); -/// } +/// // If we drop `tx`, then it will fail. +/// drop(tx); +/// assert!(tx_weak.clone().upgrade().is_none()); +/// # } /// ``` pub struct WeakUnboundedSender { chan: Arc>, @@ -135,17 +135,17 @@ impl UnboundedReceiver { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = mpsc::unbounded_channel(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = mpsc::unbounded_channel(); /// - /// tokio::spawn(async move { - /// tx.send("hello").unwrap(); - /// }); + /// tokio::spawn(async move { + /// tx.send("hello").unwrap(); + /// }); /// - /// assert_eq!(Some("hello"), rx.recv().await); - /// assert_eq!(None, rx.recv().await); - /// } + /// assert_eq!(Some("hello"), rx.recv().await); + /// assert_eq!(None, rx.recv().await); + /// # } /// ``` /// /// Values are buffered: @@ -153,16 +153,16 @@ impl UnboundedReceiver { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = mpsc::unbounded_channel(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = mpsc::unbounded_channel(); /// - /// tx.send("hello").unwrap(); - /// tx.send("world").unwrap(); + /// tx.send("hello").unwrap(); + /// tx.send("world").unwrap(); /// - /// assert_eq!(Some("hello"), rx.recv().await); - /// assert_eq!(Some("world"), rx.recv().await); - /// } + /// assert_eq!(Some("hello"), rx.recv().await); + /// assert_eq!(Some("world"), rx.recv().await); + /// # } /// ``` pub async fn recv(&mut self) -> Option { use std::future::poll_fn; @@ -203,40 +203,40 @@ impl UnboundedReceiver { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let mut buffer: Vec<&str> = Vec::with_capacity(2); - /// let limit = 2; - /// let (tx, mut rx) = mpsc::unbounded_channel(); - /// let tx2 = tx.clone(); - /// tx2.send("first").unwrap(); - /// tx2.send("second").unwrap(); - /// tx2.send("third").unwrap(); - /// - /// // Call `recv_many` to receive up to `limit` (2) values. - /// assert_eq!(2, rx.recv_many(&mut buffer, limit).await); - /// assert_eq!(vec!["first", "second"], buffer); - /// - /// // If the buffer is full, the next call to `recv_many` - /// // reserves additional capacity. - /// assert_eq!(1, rx.recv_many(&mut buffer, limit).await); - /// - /// tokio::spawn(async move { - /// tx.send("fourth").unwrap(); - /// }); - /// - /// // 'tx' is dropped, but `recv_many` - /// // is guaranteed not to return 0 as the channel - /// // is not yet closed. - /// assert_eq!(1, rx.recv_many(&mut buffer, limit).await); - /// assert_eq!(vec!["first", "second", "third", "fourth"], buffer); - /// - /// // Once the last sender is dropped, the channel is - /// // closed and `recv_many` returns 0, capacity unchanged. - /// drop(tx2); - /// assert_eq!(0, rx.recv_many(&mut buffer, limit).await); - /// assert_eq!(vec!["first", "second", "third", "fourth"], buffer); - /// } + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let mut buffer: Vec<&str> = Vec::with_capacity(2); + /// let limit = 2; + /// let (tx, mut rx) = mpsc::unbounded_channel(); + /// let tx2 = tx.clone(); + /// tx2.send("first").unwrap(); + /// tx2.send("second").unwrap(); + /// tx2.send("third").unwrap(); + /// + /// // Call `recv_many` to receive up to `limit` (2) values. + /// assert_eq!(2, rx.recv_many(&mut buffer, limit).await); + /// assert_eq!(vec!["first", "second"], buffer); + /// + /// // If the buffer is full, the next call to `recv_many` + /// // reserves additional capacity. + /// assert_eq!(1, rx.recv_many(&mut buffer, limit).await); + /// + /// tokio::spawn(async move { + /// tx.send("fourth").unwrap(); + /// }); + /// + /// // 'tx' is dropped, but `recv_many` + /// // is guaranteed not to return 0 as the channel + /// // is not yet closed. + /// assert_eq!(1, rx.recv_many(&mut buffer, limit).await); + /// assert_eq!(vec!["first", "second", "third", "fourth"], buffer); + /// + /// // Once the last sender is dropped, the channel is + /// // closed and `recv_many` returns 0, capacity unchanged. + /// drop(tx2); + /// assert_eq!(0, rx.recv_many(&mut buffer, limit).await); + /// assert_eq!(vec!["first", "second", "third", "fourth"], buffer); + /// # } /// ``` pub async fn recv_many(&mut self, buffer: &mut Vec, limit: usize) -> usize { use std::future::poll_fn; @@ -266,22 +266,22 @@ impl UnboundedReceiver { /// use tokio::sync::mpsc; /// use tokio::sync::mpsc::error::TryRecvError; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = mpsc::unbounded_channel(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = mpsc::unbounded_channel(); /// - /// tx.send("hello").unwrap(); + /// tx.send("hello").unwrap(); /// - /// assert_eq!(Ok("hello"), rx.try_recv()); - /// assert_eq!(Err(TryRecvError::Empty), rx.try_recv()); + /// assert_eq!(Ok("hello"), rx.try_recv()); + /// assert_eq!(Err(TryRecvError::Empty), rx.try_recv()); /// - /// tx.send("hello").unwrap(); - /// // Drop the last sender, closing the channel. - /// drop(tx); + /// tx.send("hello").unwrap(); + /// // Drop the last sender, closing the channel. + /// drop(tx); /// - /// assert_eq!(Ok("hello"), rx.try_recv()); - /// assert_eq!(Err(TryRecvError::Disconnected), rx.try_recv()); - /// } + /// assert_eq!(Ok("hello"), rx.try_recv()); + /// assert_eq!(Err(TryRecvError::Disconnected), rx.try_recv()); + /// # } /// ``` pub fn try_recv(&mut self) -> Result { self.chan.try_recv() @@ -297,6 +297,8 @@ impl UnboundedReceiver { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use std::thread; /// use tokio::sync::mpsc; /// @@ -311,6 +313,7 @@ impl UnboundedReceiver { /// let _ = tx.send(10); /// sync_code.join().unwrap(); /// } + /// # } /// ``` #[track_caller] #[cfg(feature = "sync")] @@ -352,15 +355,15 @@ impl UnboundedReceiver { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (_tx, mut rx) = mpsc::unbounded_channel::<()>(); - /// assert!(!rx.is_closed()); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (_tx, mut rx) = mpsc::unbounded_channel::<()>(); + /// assert!(!rx.is_closed()); /// - /// rx.close(); + /// rx.close(); /// - /// assert!(rx.is_closed()); - /// } + /// assert!(rx.is_closed()); + /// # } /// ``` pub fn is_closed(&self) -> bool { self.chan.is_closed() @@ -374,14 +377,14 @@ impl UnboundedReceiver { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, rx) = mpsc::unbounded_channel(); - /// assert!(rx.is_empty()); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, rx) = mpsc::unbounded_channel(); + /// assert!(rx.is_empty()); /// - /// tx.send(0).unwrap(); - /// assert!(!rx.is_empty()); - /// } + /// tx.send(0).unwrap(); + /// assert!(!rx.is_empty()); + /// # } /// /// ``` pub fn is_empty(&self) -> bool { @@ -394,14 +397,14 @@ impl UnboundedReceiver { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, rx) = mpsc::unbounded_channel(); - /// assert_eq!(0, rx.len()); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, rx) = mpsc::unbounded_channel(); + /// assert_eq!(0, rx.len()); /// - /// tx.send(0).unwrap(); - /// assert_eq!(1, rx.len()); - /// } + /// tx.send(0).unwrap(); + /// assert_eq!(1, rx.len()); + /// # } /// ``` pub fn len(&self) -> usize { self.chan.len() @@ -455,6 +458,8 @@ impl UnboundedReceiver { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use std::task::{Context, Poll}; /// use std::pin::Pin; /// use tokio::sync::mpsc; @@ -480,25 +485,26 @@ impl UnboundedReceiver { /// } /// } /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, rx) = mpsc::unbounded_channel::(); - /// let mut buffer = Vec::new(); - /// - /// let my_receiver_future = MyReceiverFuture { - /// receiver: rx, - /// buffer: &mut buffer, - /// limit: 3, - /// }; + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, rx) = mpsc::unbounded_channel::(); + /// let mut buffer = Vec::new(); /// - /// for i in 0..10 { - /// tx.send(i).expect("Unable to send integer"); - /// } + /// let my_receiver_future = MyReceiverFuture { + /// receiver: rx, + /// buffer: &mut buffer, + /// limit: 3, + /// }; /// - /// let count = my_receiver_future.await; - /// assert_eq!(count, 3); - /// assert_eq!(buffer, vec![0,1,2]) + /// for i in 0..10 { + /// tx.send(i).expect("Unable to send integer"); /// } + /// + /// let count = my_receiver_future.await; + /// assert_eq!(count, 3); + /// assert_eq!(buffer, vec![0,1,2]) + /// # } + /// # } /// ``` pub fn poll_recv_many( &mut self, @@ -592,26 +598,26 @@ impl UnboundedSender { /// ``` /// use tokio::sync::mpsc; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx1, rx) = mpsc::unbounded_channel::<()>(); - /// let tx2 = tx1.clone(); - /// let tx3 = tx1.clone(); - /// let tx4 = tx1.clone(); - /// let tx5 = tx1.clone(); - /// tokio::spawn(async move { - /// drop(rx); - /// }); - /// - /// futures::join!( - /// tx1.closed(), - /// tx2.closed(), - /// tx3.closed(), - /// tx4.closed(), - /// tx5.closed() - /// ); - //// println!("Receiver dropped"); - /// } + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx1, rx) = mpsc::unbounded_channel::<()>(); + /// let tx2 = tx1.clone(); + /// let tx3 = tx1.clone(); + /// let tx4 = tx1.clone(); + /// let tx5 = tx1.clone(); + /// tokio::spawn(async move { + /// drop(rx); + /// }); + /// + /// futures::join!( + /// tx1.closed(), + /// tx2.closed(), + /// tx3.closed(), + /// tx4.closed(), + /// tx5.closed() + /// ); + /// println!("Receiver dropped"); + /// # } /// ``` pub async fn closed(&self) { self.chan.closed().await; diff --git a/tokio/src/sync/mutex.rs b/tokio/src/sync/mutex.rs index 7feedc8b..2c7d8076 100644 --- a/tokio/src/sync/mutex.rs +++ b/tokio/src/sync/mutex.rs @@ -59,19 +59,19 @@ use std::{fmt, mem, ptr}; /// use tokio::sync::Mutex; /// use std::sync::Arc; /// -/// #[tokio::main] -/// async fn main() { -/// let data1 = Arc::new(Mutex::new(0)); -/// let data2 = Arc::clone(&data1); +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// let data1 = Arc::new(Mutex::new(0)); +/// let data2 = Arc::clone(&data1); /// -/// tokio::spawn(async move { -/// let mut lock = data2.lock().await; -/// *lock += 1; -/// }); -/// -/// let mut lock = data1.lock().await; +/// tokio::spawn(async move { +/// let mut lock = data2.lock().await; /// *lock += 1; -/// } +/// }); +/// +/// let mut lock = data1.lock().await; +/// *lock += 1; +/// # } /// ``` /// /// @@ -79,28 +79,28 @@ use std::{fmt, mem, ptr}; /// use tokio::sync::Mutex; /// use std::sync::Arc; /// -/// #[tokio::main] -/// async fn main() { -/// let count = Arc::new(Mutex::new(0)); +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// let count = Arc::new(Mutex::new(0)); /// -/// for i in 0..5 { -/// let my_count = Arc::clone(&count); -/// tokio::spawn(async move { -/// for j in 0..10 { -/// let mut lock = my_count.lock().await; -/// *lock += 1; -/// println!("{} {} {}", i, j, lock); -/// } -/// }); -/// } -/// -/// loop { -/// if *count.lock().await >= 50 { -/// break; +/// for i in 0..5 { +/// let my_count = Arc::clone(&count); +/// tokio::spawn(async move { +/// for j in 0..10 { +/// let mut lock = my_count.lock().await; +/// *lock += 1; +/// println!("{} {} {}", i, j, lock); /// } +/// }); +/// } +/// +/// loop { +/// if *count.lock().await >= 50 { +/// break; /// } -/// println!("Count hit 50."); /// } +/// println!("Count hit 50."); +/// # } /// ``` /// There are a few things of note here to pay attention to in this example. /// 1. The mutex is wrapped in an [`Arc`] to allow it to be shared across @@ -423,13 +423,13 @@ impl Mutex { /// ``` /// use tokio::sync::Mutex; /// - /// #[tokio::main] - /// async fn main() { - /// let mutex = Mutex::new(1); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let mutex = Mutex::new(1); /// - /// let mut n = mutex.lock().await; - /// *n = 2; - /// } + /// let mut n = mutex.lock().await; + /// *n = 2; + /// # } /// ``` pub async fn lock(&self) -> MutexGuard<'_, T> { let acquire_fut = async { @@ -484,6 +484,8 @@ impl Mutex { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use std::sync::Arc; /// use tokio::sync::Mutex; /// @@ -510,7 +512,7 @@ impl Mutex { /// let n = mutex.try_lock().unwrap(); /// assert_eq!(*n, 2); /// } - /// + /// # } /// ``` #[track_caller] #[cfg(feature = "sync")] @@ -541,6 +543,8 @@ impl Mutex { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use std::sync::Arc; /// use tokio::sync::Mutex; /// @@ -567,7 +571,7 @@ impl Mutex { /// let n = mutex.try_lock().unwrap(); /// assert_eq!(*n, 2); /// } - /// + /// # } /// ``` #[track_caller] #[cfg(feature = "sync")] @@ -601,13 +605,13 @@ impl Mutex { /// use tokio::sync::Mutex; /// use std::sync::Arc; /// - /// #[tokio::main] - /// async fn main() { - /// let mutex = Arc::new(Mutex::new(1)); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let mutex = Arc::new(Mutex::new(1)); /// - /// let mut n = mutex.clone().lock_owned().await; - /// *n = 2; - /// } + /// let mut n = mutex.clone().lock_owned().await; + /// *n = 2; + /// # } /// ``` /// /// [`Arc`]: std::sync::Arc @@ -772,13 +776,13 @@ impl Mutex { /// ``` /// use tokio::sync::Mutex; /// - /// #[tokio::main] - /// async fn main() { - /// let mutex = Mutex::new(1); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let mutex = Mutex::new(1); /// - /// let n = mutex.into_inner(); - /// assert_eq!(n, 1); - /// } + /// let n = mutex.into_inner(); + /// assert_eq!(n, 1); + /// # } /// ``` pub fn into_inner(self) -> T where @@ -846,7 +850,7 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> { /// #[derive(Debug, Clone, Copy, PartialEq, Eq)] /// struct Foo(u32); /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let foo = Mutex::new(Foo(1)); /// @@ -894,7 +898,7 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> { /// #[derive(Debug, Clone, Copy, PartialEq, Eq)] /// struct Foo(u32); /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let foo = Mutex::new(Foo(1)); /// @@ -944,7 +948,7 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> { /// guard /// } /// # - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// # let mutex = Mutex::new(0u32); /// # let guard = mutex.lock().await; @@ -1028,7 +1032,7 @@ impl OwnedMutexGuard { /// #[derive(Debug, Clone, Copy, PartialEq, Eq)] /// struct Foo(u32); /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let foo = Arc::new(Mutex::new(Foo(1))); /// @@ -1076,7 +1080,7 @@ impl OwnedMutexGuard { /// #[derive(Debug, Clone, Copy, PartialEq, Eq)] /// struct Foo(u32); /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let foo = Arc::new(Mutex::new(Foo(1))); /// @@ -1126,7 +1130,7 @@ impl OwnedMutexGuard { /// guard /// } /// # - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// # let mutex = Arc::new(Mutex::new(0u32)); /// # let guard = mutex.lock_owned().await; diff --git a/tokio/src/sync/notify.rs b/tokio/src/sync/notify.rs index b79c14d8..f78da7dc 100644 --- a/tokio/src/sync/notify.rs +++ b/tokio/src/sync/notify.rs @@ -56,22 +56,22 @@ type GuardedWaitList = GuardedLinkedList:: /// use tokio::sync::Notify; /// use std::sync::Arc; /// -/// #[tokio::main] -/// async fn main() { -/// let notify = Arc::new(Notify::new()); -/// let notify2 = notify.clone(); +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// let notify = Arc::new(Notify::new()); +/// let notify2 = notify.clone(); /// -/// let handle = tokio::spawn(async move { -/// notify2.notified().await; -/// println!("received notification"); -/// }); +/// let handle = tokio::spawn(async move { +/// notify2.notified().await; +/// println!("received notification"); +/// }); /// -/// println!("sending notification"); -/// notify.notify_one(); +/// println!("sending notification"); +/// notify.notify_one(); /// -/// // Wait for task to receive notification. -/// handle.await.unwrap(); -/// } +/// // Wait for task to receive notification. +/// handle.await.unwrap(); +/// # } /// ``` /// /// Unbound multi-producer single-consumer (mpsc) channel. @@ -548,19 +548,19 @@ impl Notify { /// use tokio::sync::Notify; /// use std::sync::Arc; /// - /// #[tokio::main] - /// async fn main() { - /// let notify = Arc::new(Notify::new()); - /// let notify2 = notify.clone(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let notify = Arc::new(Notify::new()); + /// let notify2 = notify.clone(); /// - /// tokio::spawn(async move { - /// notify2.notified().await; - /// println!("received notification"); - /// }); + /// tokio::spawn(async move { + /// notify2.notified().await; + /// println!("received notification"); + /// }); /// - /// println!("sending notification"); - /// notify.notify_one(); - /// } + /// println!("sending notification"); + /// notify.notify_one(); + /// # } /// ``` pub fn notified(&self) -> Notified<'_> { // we load the number of times notify_waiters @@ -594,21 +594,21 @@ impl Notify { /// use std::sync::Arc; /// use tokio::sync::Notify; /// - /// #[tokio::main] - /// async fn main() { - /// let notify = Arc::new(Notify::new()); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let notify = Arc::new(Notify::new()); /// - /// for _ in 0..10 { - /// let notified = notify.clone().notified_owned(); - /// tokio::spawn(async move { - /// notified.await; - /// println!("received notification"); - /// }); - /// } - /// - /// println!("sending notification"); - /// notify.notify_waiters(); + /// for _ in 0..10 { + /// let notified = notify.clone().notified_owned(); + /// tokio::spawn(async move { + /// notified.await; + /// println!("received notification"); + /// }); /// } + /// + /// println!("sending notification"); + /// notify.notify_waiters(); + /// # } /// ``` pub fn notified_owned(self: Arc) -> OwnedNotified { // we load the number of times notify_waiters @@ -641,19 +641,19 @@ impl Notify { /// use tokio::sync::Notify; /// use std::sync::Arc; /// - /// #[tokio::main] - /// async fn main() { - /// let notify = Arc::new(Notify::new()); - /// let notify2 = notify.clone(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let notify = Arc::new(Notify::new()); + /// let notify2 = notify.clone(); /// - /// tokio::spawn(async move { - /// notify2.notified().await; - /// println!("received notification"); - /// }); + /// tokio::spawn(async move { + /// notify2.notified().await; + /// println!("received notification"); + /// }); /// - /// println!("sending notification"); - /// notify.notify_one(); - /// } + /// println!("sending notification"); + /// notify.notify_one(); + /// # } /// ``` // Alias for old name in 0.x #[cfg_attr(docsrs, doc(alias = "notify"))] @@ -722,23 +722,23 @@ impl Notify { /// use tokio::sync::Notify; /// use std::sync::Arc; /// - /// #[tokio::main] - /// async fn main() { - /// let notify = Arc::new(Notify::new()); - /// let notify2 = notify.clone(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let notify = Arc::new(Notify::new()); + /// let notify2 = notify.clone(); /// - /// let notified1 = notify.notified(); - /// let notified2 = notify.notified(); + /// let notified1 = notify.notified(); + /// let notified2 = notify.notified(); /// - /// let handle = tokio::spawn(async move { - /// println!("sending notifications"); - /// notify2.notify_waiters(); - /// }); + /// let handle = tokio::spawn(async move { + /// println!("sending notifications"); + /// notify2.notify_waiters(); + /// }); /// - /// notified1.await; - /// notified2.await; - /// println!("received notifications"); - /// } + /// notified1.await; + /// notified2.await; + /// println!("received notifications"); + /// # } /// ``` pub fn notify_waiters(&self) { self.lock_waiter_list().notify_waiters(); diff --git a/tokio/src/sync/once_cell.rs b/tokio/src/sync/once_cell.rs index 1b723048..92194a54 100644 --- a/tokio/src/sync/once_cell.rs +++ b/tokio/src/sync/once_cell.rs @@ -41,11 +41,11 @@ use std::sync::atomic::{AtomicBool, Ordering}; /// /// static ONCE: OnceCell = OnceCell::const_new(); /// -/// #[tokio::main] -/// async fn main() { -/// let result = ONCE.get_or_init(some_computation).await; -/// assert_eq!(*result, 2); -/// } +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// let result = ONCE.get_or_init(some_computation).await; +/// assert_eq!(*result, 2); +/// # } /// ``` /// /// It is often useful to write a wrapper method for accessing the value. @@ -61,11 +61,11 @@ use std::sync::atomic::{AtomicBool, Ordering}; /// }).await /// } /// -/// #[tokio::main] -/// async fn main() { -/// let result = get_global_integer().await; -/// assert_eq!(*result, 2); -/// } +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// let result = get_global_integer().await; +/// assert_eq!(*result, 2); +/// # } /// ``` pub struct OnceCell { value_set: AtomicBool, @@ -155,11 +155,11 @@ impl OnceCell { /// }).await /// } /// - /// #[tokio::main] - /// async fn main() { - /// let result = get_global_integer().await; - /// assert_eq!(*result, 2); - /// } + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let result = get_global_integer().await; + /// assert_eq!(*result, 2); + /// # } /// ``` /// /// [`tokio-console`]: https://github.com/tokio-rs/console @@ -210,11 +210,11 @@ impl OnceCell { /// }).await /// } /// - /// #[tokio::main] - /// async fn main() { - /// let result = get_global_integer().await; - /// assert_eq!(*result, 1); - /// } + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let result = get_global_integer().await; + /// assert_eq!(*result, 1); + /// # } /// ``` /// /// [`tokio-console`]: https://github.com/tokio-rs/console diff --git a/tokio/src/sync/oneshot.rs b/tokio/src/sync/oneshot.rs index 719745c7..a93cea23 100644 --- a/tokio/src/sync/oneshot.rs +++ b/tokio/src/sync/oneshot.rs @@ -21,21 +21,21 @@ //! ``` //! use tokio::sync::oneshot; //! -//! #[tokio::main] -//! async fn main() { -//! let (tx, rx) = oneshot::channel(); -//! -//! tokio::spawn(async move { -//! if let Err(_) = tx.send(3) { -//! println!("the receiver dropped"); -//! } -//! }); +//! # #[tokio::main(flavor = "current_thread")] +//! # async fn main() { +//! let (tx, rx) = oneshot::channel(); //! -//! match rx.await { -//! Ok(v) => println!("got = {:?}", v), -//! Err(_) => println!("the sender dropped"), +//! 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 @@ -44,19 +44,19 @@ //! ``` //! use tokio::sync::oneshot; //! -//! #[tokio::main] -//! async fn main() { -//! let (tx, rx) = oneshot::channel::(); +//! # #[tokio::main(flavor = "current_thread")] +//! # async fn main() { +//! let (tx, rx) = oneshot::channel::(); //! -//! tokio::spawn(async move { -//! drop(tx); -//! }); +//! tokio::spawn(async move { +//! drop(tx); +//! }); //! -//! match rx.await { -//! Ok(_) => panic!("This doesn't happen"), -//! Err(_) => println!("the sender dropped"), -//! } +//! 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 @@ -66,30 +66,30 @@ //! use tokio::sync::oneshot; //! use tokio::time::{interval, sleep, Duration}; //! -//! #[tokio::main] +//! # #[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)); +//! # 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(); -//! }); +//! # 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; -//! } +//! loop { +//! tokio::select! { +//! _ = interval.tick() => println!("Another 100ms"), +//! msg = &mut recv => { +//! println!("Got message: {}", msg.unwrap()); +//! break; //! } //! } -//! # handle.await.unwrap(); //! } +//! # handle.await.unwrap(); +//! # } //! ``` //! //! To use a `Sender` from a destructor, put it in an [`Option`] and call @@ -110,17 +110,17 @@ //! } //! } //! -//! #[tokio::main] +//! # #[tokio::main(flavor = "current_thread")] //! # async fn _doc() {} //! # #[tokio::main(flavor = "current_thread")] -//! async fn main() { -//! let (send, recv) = oneshot::channel(); +//! # async fn main() { +//! let (send, recv) = oneshot::channel(); //! -//! let send_on_drop = SendOnDrop { sender: Some(send) }; -//! drop(send_on_drop); +//! let send_on_drop = SendOnDrop { sender: Some(send) }; +//! drop(send_on_drop); //! -//! assert_eq!(recv.await, Ok("I got dropped!")); -//! } +//! assert_eq!(recv.await, Ok("I got dropped!")); +//! # } //! ``` use crate::loom::cell::UnsafeCell; @@ -147,21 +147,21 @@ use std::task::{ready, Context, Poll, Waker}; /// ``` /// use tokio::sync::oneshot; /// -/// #[tokio::main] -/// async fn main() { -/// let (tx, rx) = oneshot::channel(); -/// -/// tokio::spawn(async move { -/// if let Err(_) = tx.send(3) { -/// println!("the receiver dropped"); -/// } -/// }); +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// let (tx, rx) = oneshot::channel(); /// -/// match rx.await { -/// Ok(v) => println!("got = {:?}", v), -/// Err(_) => println!("the sender dropped"), +/// 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 @@ -170,19 +170,19 @@ use std::task::{ready, Context, Poll, Waker}; /// ``` /// use tokio::sync::oneshot; /// -/// #[tokio::main] -/// async fn main() { -/// let (tx, rx) = oneshot::channel::(); +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// let (tx, rx) = oneshot::channel::(); /// -/// tokio::spawn(async move { -/// drop(tx); -/// }); +/// tokio::spawn(async move { +/// drop(tx); +/// }); /// -/// match rx.await { -/// Ok(_) => panic!("This doesn't happen"), -/// Err(_) => println!("the sender dropped"), -/// } +/// 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 @@ -203,17 +203,17 @@ use std::task::{ready, Context, Poll, Waker}; /// } /// } /// -/// #[tokio::main] +/// # #[tokio::main(flavor = "current_thread")] /// # async fn _doc() {} /// # #[tokio::main(flavor = "current_thread")] -/// async fn main() { -/// let (send, recv) = oneshot::channel(); +/// # async fn main() { +/// let (send, recv) = oneshot::channel(); /// -/// let send_on_drop = SendOnDrop { sender: Some(send) }; -/// drop(send_on_drop); +/// let send_on_drop = SendOnDrop { sender: Some(send) }; +/// drop(send_on_drop); /// -/// assert_eq!(recv.await, Ok("I got dropped!")); -/// } +/// assert_eq!(recv.await, Ok("I got dropped!")); +/// # } /// ``` /// /// [`Option`]: std::option::Option @@ -248,21 +248,21 @@ pub struct Sender { /// ``` /// use tokio::sync::oneshot; /// -/// #[tokio::main] -/// async fn main() { -/// let (tx, rx) = oneshot::channel(); -/// -/// tokio::spawn(async move { -/// if let Err(_) = tx.send(3) { -/// println!("the receiver dropped"); -/// } -/// }); +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// let (tx, rx) = oneshot::channel(); /// -/// match rx.await { -/// Ok(v) => println!("got = {:?}", v), -/// Err(_) => println!("the sender dropped"), +/// 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 @@ -271,19 +271,19 @@ pub struct Sender { /// ``` /// use tokio::sync::oneshot; /// -/// #[tokio::main] -/// async fn main() { -/// let (tx, rx) = oneshot::channel::(); +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// let (tx, rx) = oneshot::channel::(); /// -/// tokio::spawn(async move { -/// drop(tx); -/// }); +/// tokio::spawn(async move { +/// drop(tx); +/// }); /// -/// match rx.await { -/// Ok(_) => panic!("This doesn't happen"), -/// Err(_) => println!("the sender dropped"), -/// } +/// 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 @@ -293,30 +293,30 @@ pub struct Sender { /// use tokio::sync::oneshot; /// use tokio::time::{interval, sleep, Duration}; /// -/// #[tokio::main] +/// # #[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)); +/// # 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(); -/// }); +/// # 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; -/// } +/// loop { +/// tokio::select! { +/// _ = interval.tick() => println!("Another 100ms"), +/// msg = &mut recv => { +/// println!("Got message: {}", msg.unwrap()); +/// break; /// } /// } -/// # handle.await.unwrap(); /// } +/// # handle.await.unwrap(); +/// # } /// ``` #[derive(Debug)] pub struct Receiver { @@ -450,21 +450,21 @@ struct State(usize); /// ``` /// use tokio::sync::oneshot; /// -/// #[tokio::main] -/// async fn main() { -/// let (tx, rx) = oneshot::channel(); -/// -/// tokio::spawn(async move { -/// if let Err(_) = tx.send(3) { -/// println!("the receiver dropped"); -/// } -/// }); +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// let (tx, rx) = oneshot::channel(); /// -/// match rx.await { -/// Ok(v) => println!("got = {:?}", v), -/// Err(_) => println!("the sender dropped"), +/// 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"), /// } +/// # } /// ``` #[track_caller] pub fn channel() -> (Sender, Receiver) { @@ -576,21 +576,21 @@ impl Sender { /// ``` /// use tokio::sync::oneshot; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, rx) = oneshot::channel(); - /// - /// tokio::spawn(async move { - /// if let Err(_) = tx.send(3) { - /// println!("the receiver dropped"); - /// } - /// }); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, rx) = oneshot::channel(); /// - /// match rx.await { - /// Ok(v) => println!("got = {:?}", v), - /// Err(_) => println!("the sender dropped"), + /// 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"), /// } + /// # } /// ``` pub fn send(mut self, t: T) -> Result<(), T> { let inner = self.inner.take().unwrap(); @@ -652,17 +652,17 @@ impl Sender { /// ``` /// use tokio::sync::oneshot; /// - /// #[tokio::main] - /// async fn main() { - /// let (mut tx, rx) = oneshot::channel::<()>(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (mut tx, rx) = oneshot::channel::<()>(); /// - /// tokio::spawn(async move { - /// drop(rx); - /// }); + /// tokio::spawn(async move { + /// drop(rx); + /// }); /// - /// tx.closed().await; - /// println!("the receiver dropped"); - /// } + /// tx.closed().await; + /// println!("the receiver dropped"); + /// # } /// ``` /// /// Paired with select @@ -676,26 +676,26 @@ impl Sender { /// # "hello".to_string() /// } /// - /// #[tokio::main] - /// async fn main() { - /// let (mut tx, rx) = oneshot::channel(); - /// - /// tokio::spawn(async move { - /// tokio::select! { - /// _ = tx.closed() => { - /// // The receiver dropped, no need to do any further work - /// } - /// value = compute() => { - /// // The send can fail if the channel was closed at the exact same - /// // time as when compute() finished, so just ignore the failure. - /// let _ = tx.send(value); - /// } + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (mut tx, rx) = oneshot::channel(); + /// + /// tokio::spawn(async move { + /// tokio::select! { + /// _ = tx.closed() => { + /// // The receiver dropped, no need to do any further work /// } - /// }); + /// value = compute() => { + /// // The send can fail if the channel was closed at the exact same + /// // time as when compute() finished, so just ignore the failure. + /// let _ = tx.send(value); + /// } + /// } + /// }); /// - /// // Wait for up to 10 seconds - /// let _ = time::timeout(Duration::from_secs(10), rx).await; - /// } + /// // Wait for up to 10 seconds + /// let _ = time::timeout(Duration::from_secs(10), rx).await; + /// # } /// ``` pub async fn closed(&mut self) { use std::future::poll_fn; @@ -731,17 +731,17 @@ impl Sender { /// ``` /// use tokio::sync::oneshot; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, rx) = oneshot::channel(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, rx) = oneshot::channel(); /// - /// assert!(!tx.is_closed()); + /// assert!(!tx.is_closed()); /// - /// drop(rx); + /// drop(rx); /// - /// assert!(tx.is_closed()); - /// assert!(tx.send("never received").is_err()); - /// } + /// assert!(tx.is_closed()); + /// assert!(tx.send("never received").is_err()); + /// # } /// ``` pub fn is_closed(&self) -> bool { let inner = self.inner.as_ref().unwrap(); @@ -777,18 +777,18 @@ impl Sender { /// /// use std::future::poll_fn; /// - /// #[tokio::main] - /// async fn main() { - /// let (mut tx, mut rx) = oneshot::channel::<()>(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (mut tx, mut rx) = oneshot::channel::<()>(); /// - /// tokio::spawn(async move { - /// rx.close(); - /// }); + /// tokio::spawn(async move { + /// rx.close(); + /// }); /// - /// poll_fn(|cx| tx.poll_closed(cx)).await; + /// poll_fn(|cx| tx.poll_closed(cx)).await; /// - /// println!("the receiver dropped"); - /// } + /// println!("the receiver dropped"); + /// # } /// ``` pub fn poll_closed(&mut self, cx: &mut Context<'_>) -> Poll<()> { ready!(crate::trace::trace_leaf(cx)); @@ -882,22 +882,22 @@ impl Receiver { /// use tokio::sync::oneshot; /// use tokio::sync::oneshot::error::TryRecvError; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = oneshot::channel(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = oneshot::channel(); /// - /// assert!(!tx.is_closed()); + /// assert!(!tx.is_closed()); /// - /// rx.close(); + /// rx.close(); /// - /// assert!(tx.is_closed()); - /// assert!(tx.send("never received").is_err()); + /// assert!(tx.is_closed()); + /// assert!(tx.send("never received").is_err()); /// - /// match rx.try_recv() { - /// Err(TryRecvError::Closed) => {} - /// _ => unreachable!(), - /// } + /// match rx.try_recv() { + /// Err(TryRecvError::Closed) => {} + /// _ => unreachable!(), /// } + /// # } /// ``` /// /// Receive a value sent **before** calling `close` @@ -905,17 +905,17 @@ impl Receiver { /// ``` /// use tokio::sync::oneshot; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = oneshot::channel(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = oneshot::channel(); /// - /// assert!(tx.send("will receive").is_ok()); + /// assert!(tx.send("will receive").is_ok()); /// - /// rx.close(); + /// rx.close(); /// - /// let msg = rx.try_recv().unwrap(); - /// assert_eq!(msg, "will receive"); - /// } + /// let msg = rx.try_recv().unwrap(); + /// assert_eq!(msg, "will receive"); + /// # } /// ``` pub fn close(&mut self) { if let Some(inner) = self.inner.as_ref() { @@ -945,26 +945,26 @@ impl Receiver { /// /// use std::task::Poll; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = oneshot::channel(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = oneshot::channel(); /// - /// // A receiver is not terminated when it is initialized. - /// assert!(!rx.is_terminated()); + /// // A receiver is not terminated when it is initialized. + /// assert!(!rx.is_terminated()); /// - /// // A receiver is not terminated it is polled and is still pending. - /// let poll = futures::poll!(&mut rx); - /// assert_eq!(poll, Poll::Pending); - /// assert!(!rx.is_terminated()); + /// // A receiver is not terminated it is polled and is still pending. + /// let poll = futures::poll!(&mut rx); + /// assert_eq!(poll, Poll::Pending); + /// assert!(!rx.is_terminated()); /// - /// // A receiver is not terminated if a value has been sent, but not yet read. - /// tx.send(0).unwrap(); - /// assert!(!rx.is_terminated()); + /// // A receiver is not terminated if a value has been sent, but not yet read. + /// tx.send(0).unwrap(); + /// assert!(!rx.is_terminated()); /// - /// // A receiver *is* terminated after it has been polled and yielded a value. - /// assert_eq!((&mut rx).await, Ok(0)); - /// assert!(rx.is_terminated()); - /// } + /// // A receiver *is* terminated after it has been polled and yielded a value. + /// assert_eq!((&mut rx).await, Ok(0)); + /// assert!(rx.is_terminated()); + /// # } /// ``` /// /// Dropping the sender. @@ -972,18 +972,18 @@ impl Receiver { /// ``` /// use tokio::sync::oneshot; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = oneshot::channel::<()>(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = oneshot::channel::<()>(); /// - /// // A receiver is not immediately terminated when the sender is dropped. - /// drop(tx); - /// assert!(!rx.is_terminated()); + /// // A receiver is not immediately terminated when the sender is dropped. + /// drop(tx); + /// assert!(!rx.is_terminated()); /// - /// // A receiver *is* terminated after it has been polled and yielded an error. - /// let _ = (&mut rx).await.unwrap_err(); - /// assert!(rx.is_terminated()); - /// } + /// // A receiver *is* terminated after it has been polled and yielded an error. + /// let _ = (&mut rx).await.unwrap_err(); + /// assert!(rx.is_terminated()); + /// # } /// ``` pub fn is_terminated(&self) -> bool { self.inner.is_none() @@ -1004,17 +1004,17 @@ impl Receiver { /// ``` /// use tokio::sync::oneshot; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = oneshot::channel(); - /// assert!(rx.is_empty()); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = oneshot::channel(); + /// assert!(rx.is_empty()); /// - /// tx.send(0).unwrap(); - /// assert!(!rx.is_empty()); + /// tx.send(0).unwrap(); + /// assert!(!rx.is_empty()); /// - /// let _ = (&mut rx).await; - /// assert!(rx.is_empty()); - /// } + /// let _ = (&mut rx).await; + /// assert!(rx.is_empty()); + /// # } /// ``` /// /// Dropping the sender. @@ -1022,23 +1022,23 @@ impl Receiver { /// ``` /// use tokio::sync::oneshot; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = oneshot::channel::<()>(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = oneshot::channel::<()>(); /// - /// // A channel is empty if the sender is dropped. - /// drop(tx); - /// assert!(rx.is_empty()); + /// // A channel is empty if the sender is dropped. + /// drop(tx); + /// assert!(rx.is_empty()); /// - /// // A closed channel still yields an error, however. - /// (&mut rx).await.expect_err("should yield an error"); - /// assert!(rx.is_empty()); - /// } + /// // A closed channel still yields an error, however. + /// (&mut rx).await.expect_err("should yield an error"); + /// assert!(rx.is_empty()); + /// # } /// ``` /// /// Terminated channels are empty. /// - /// ```should_panic + /// ```should_panic,ignore-wasm /// use tokio::sync::oneshot; /// /// #[tokio::main] @@ -1102,24 +1102,24 @@ impl Receiver { /// use tokio::sync::oneshot; /// use tokio::sync::oneshot::error::TryRecvError; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = oneshot::channel(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = oneshot::channel(); /// - /// match rx.try_recv() { - /// // The channel is currently empty - /// Err(TryRecvError::Empty) => {} - /// _ => unreachable!(), - /// } + /// match rx.try_recv() { + /// // The channel is currently empty + /// Err(TryRecvError::Empty) => {} + /// _ => unreachable!(), + /// } /// - /// // Send a value - /// tx.send("hello").unwrap(); + /// // Send a value + /// tx.send("hello").unwrap(); /// - /// match rx.try_recv() { - /// Ok(value) => assert_eq!(value, "hello"), - /// _ => unreachable!(), - /// } + /// match rx.try_recv() { + /// Ok(value) => assert_eq!(value, "hello"), + /// _ => unreachable!(), /// } + /// # } /// ``` /// /// `try_recv` when the sender dropped before sending a value @@ -1128,18 +1128,18 @@ impl Receiver { /// use tokio::sync::oneshot; /// use tokio::sync::oneshot::error::TryRecvError; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = oneshot::channel::<()>(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = oneshot::channel::<()>(); /// - /// drop(tx); + /// drop(tx); /// - /// match rx.try_recv() { - /// // The channel will never receive a value. - /// Err(TryRecvError::Closed) => {} - /// _ => unreachable!(), - /// } + /// match rx.try_recv() { + /// // The channel will never receive a value. + /// Err(TryRecvError::Closed) => {} + /// _ => unreachable!(), /// } + /// # } /// ``` pub fn try_recv(&mut self) -> Result { let result = if let Some(inner) = self.inner.as_ref() { @@ -1189,6 +1189,8 @@ impl Receiver { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use std::thread; /// use tokio::sync::oneshot; /// @@ -1203,6 +1205,7 @@ impl Receiver { /// let _ = tx.send(10); /// sync_code.join().unwrap(); /// } + /// # } /// ``` #[track_caller] #[cfg(feature = "sync")] diff --git a/tokio/src/sync/rwlock.rs b/tokio/src/sync/rwlock.rs index 087c5b3d..c8a35db2 100644 --- a/tokio/src/sync/rwlock.rs +++ b/tokio/src/sync/rwlock.rs @@ -58,25 +58,25 @@ const MAX_READS: u32 = 10; /// ``` /// use tokio::sync::RwLock; /// -/// #[tokio::main] -/// async fn main() { -/// let lock = RwLock::new(5); +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// let lock = RwLock::new(5); /// -/// // many reader locks can be held at once -/// { -/// let r1 = lock.read().await; -/// let r2 = lock.read().await; -/// assert_eq!(*r1, 5); -/// assert_eq!(*r2, 5); -/// } // read locks are dropped at this point +/// // many reader locks can be held at once +/// { +/// let r1 = lock.read().await; +/// let r2 = lock.read().await; +/// assert_eq!(*r1, 5); +/// assert_eq!(*r2, 5); +/// } // read locks are dropped at this point /// -/// // only one write lock may be held, however -/// { -/// let mut w = lock.write().await; -/// *w += 1; -/// assert_eq!(*w, 6); -/// } // write lock is dropped here -/// } +/// // only one write lock may be held, however +/// { +/// let mut w = lock.write().await; +/// *w += 1; +/// assert_eq!(*w, 6); +/// } // write lock is dropped here +/// # } /// ``` /// /// [`Mutex`]: struct@super::Mutex @@ -410,23 +410,23 @@ impl RwLock { /// use std::sync::Arc; /// use tokio::sync::RwLock; /// - /// #[tokio::main] - /// async fn main() { - /// let lock = Arc::new(RwLock::new(1)); - /// let c_lock = lock.clone(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let lock = Arc::new(RwLock::new(1)); + /// let c_lock = lock.clone(); /// - /// let n = lock.read().await; - /// assert_eq!(*n, 1); + /// let n = lock.read().await; + /// assert_eq!(*n, 1); /// - /// tokio::spawn(async move { - /// // While main has an active read lock, we acquire one too. - /// let r = c_lock.read().await; - /// assert_eq!(*r, 1); - /// }).await.expect("The spawned task has panicked"); + /// tokio::spawn(async move { + /// // While main has an active read lock, we acquire one too. + /// let r = c_lock.read().await; + /// assert_eq!(*r, 1); + /// }).await.expect("The spawned task has panicked"); /// - /// // Drop the guard after the spawned task finishes. - /// drop(n); - /// } + /// // Drop the guard after the spawned task finishes. + /// drop(n); + /// # } /// ``` pub async fn read(&self) -> RwLockReadGuard<'_, T> { let acquire_fut = async { @@ -489,6 +489,8 @@ impl RwLock { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use std::sync::Arc; /// use tokio::sync::RwLock; /// @@ -515,6 +517,7 @@ impl RwLock { /// // Assert uncontended. /// assert!(rwlock.try_write().is_ok()); /// } + /// # } /// ``` #[track_caller] #[cfg(feature = "sync")] @@ -555,22 +558,22 @@ impl RwLock { /// use std::sync::Arc; /// use tokio::sync::RwLock; /// - /// #[tokio::main] - /// async fn main() { - /// let lock = Arc::new(RwLock::new(1)); - /// let c_lock = lock.clone(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let lock = Arc::new(RwLock::new(1)); + /// let c_lock = lock.clone(); /// - /// let n = lock.read_owned().await; - /// assert_eq!(*n, 1); + /// let n = lock.read_owned().await; + /// assert_eq!(*n, 1); /// - /// tokio::spawn(async move { - /// // While main has an active read lock, we acquire one too. - /// let r = c_lock.read_owned().await; - /// assert_eq!(*r, 1); - /// }).await.expect("The spawned task has panicked"); + /// tokio::spawn(async move { + /// // While main has an active read lock, we acquire one too. + /// let r = c_lock.read_owned().await; + /// assert_eq!(*r, 1); + /// }).await.expect("The spawned task has panicked"); /// - /// // Drop the guard after the spawned task finishes. - /// drop(n); + /// // Drop the guard after the spawned task finishes. + /// drop(n); ///} /// ``` pub async fn read_owned(self: Arc) -> OwnedRwLockReadGuard { @@ -631,23 +634,23 @@ impl RwLock { /// use std::sync::Arc; /// use tokio::sync::RwLock; /// - /// #[tokio::main] - /// async fn main() { - /// let lock = Arc::new(RwLock::new(1)); - /// let c_lock = lock.clone(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let lock = Arc::new(RwLock::new(1)); + /// let c_lock = lock.clone(); /// - /// let v = lock.try_read().unwrap(); - /// assert_eq!(*v, 1); + /// let v = lock.try_read().unwrap(); + /// assert_eq!(*v, 1); /// - /// tokio::spawn(async move { - /// // While main has an active read lock, we acquire one too. - /// let n = c_lock.read().await; - /// assert_eq!(*n, 1); - /// }).await.expect("The spawned task has panicked"); + /// tokio::spawn(async move { + /// // While main has an active read lock, we acquire one too. + /// let n = c_lock.read().await; + /// assert_eq!(*n, 1); + /// }).await.expect("The spawned task has panicked"); /// - /// // Drop the guard when spawned task finishes. - /// drop(v); - /// } + /// // Drop the guard when spawned task finishes. + /// drop(v); + /// # } /// ``` pub fn try_read(&self) -> Result, TryLockError> { match self.s.try_acquire(1) { @@ -696,23 +699,23 @@ impl RwLock { /// use std::sync::Arc; /// use tokio::sync::RwLock; /// - /// #[tokio::main] - /// async fn main() { - /// let lock = Arc::new(RwLock::new(1)); - /// let c_lock = lock.clone(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let lock = Arc::new(RwLock::new(1)); + /// let c_lock = lock.clone(); /// - /// let v = lock.try_read_owned().unwrap(); - /// assert_eq!(*v, 1); + /// let v = lock.try_read_owned().unwrap(); + /// assert_eq!(*v, 1); /// - /// tokio::spawn(async move { - /// // While main has an active read lock, we acquire one too. - /// let n = c_lock.read_owned().await; - /// assert_eq!(*n, 1); - /// }).await.expect("The spawned task has panicked"); + /// tokio::spawn(async move { + /// // While main has an active read lock, we acquire one too. + /// let n = c_lock.read_owned().await; + /// assert_eq!(*n, 1); + /// }).await.expect("The spawned task has panicked"); /// - /// // Drop the guard when spawned task finishes. - /// drop(v); - /// } + /// // Drop the guard when spawned task finishes. + /// drop(v); + /// # } /// ``` pub fn try_read_owned(self: Arc) -> Result, TryLockError> { match self.s.try_acquire(1) { @@ -761,13 +764,13 @@ impl RwLock { /// ``` /// use tokio::sync::RwLock; /// - /// #[tokio::main] - /// async fn main() { - /// let lock = RwLock::new(1); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let lock = RwLock::new(1); /// - /// let mut n = lock.write().await; - /// *n = 2; - ///} + /// let mut n = lock.write().await; + /// *n = 2; + /// # } /// ``` pub async fn write(&self) -> RwLockWriteGuard<'_, T> { let acquire_fut = async { @@ -831,6 +834,8 @@ impl RwLock { /// # Examples /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use std::sync::Arc; /// use tokio::{sync::RwLock}; /// @@ -859,6 +864,7 @@ impl RwLock { /// let read_lock = rwlock.try_read().unwrap(); /// assert_eq!(*read_lock, 2); /// } + /// # } /// ``` #[track_caller] #[cfg(feature = "sync")] @@ -893,12 +899,12 @@ impl RwLock { /// use std::sync::Arc; /// use tokio::sync::RwLock; /// - /// #[tokio::main] - /// async fn main() { - /// let lock = Arc::new(RwLock::new(1)); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let lock = Arc::new(RwLock::new(1)); /// - /// let mut n = lock.write_owned().await; - /// *n = 2; + /// let mut n = lock.write_owned().await; + /// *n = 2; ///} /// ``` pub async fn write_owned(self: Arc) -> OwnedRwLockWriteGuard { @@ -959,15 +965,15 @@ impl RwLock { /// ``` /// use tokio::sync::RwLock; /// - /// #[tokio::main] - /// async fn main() { - /// let rw = RwLock::new(1); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let rw = RwLock::new(1); /// - /// let v = rw.read().await; - /// assert_eq!(*v, 1); + /// let v = rw.read().await; + /// assert_eq!(*v, 1); /// - /// assert!(rw.try_write().is_err()); - /// } + /// assert!(rw.try_write().is_err()); + /// # } /// ``` pub fn try_write(&self) -> Result, TryLockError> { match self.s.try_acquire(self.mr as usize) { @@ -1017,15 +1023,15 @@ impl RwLock { /// use std::sync::Arc; /// use tokio::sync::RwLock; /// - /// #[tokio::main] - /// async fn main() { - /// let rw = Arc::new(RwLock::new(1)); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let rw = Arc::new(RwLock::new(1)); /// - /// let v = Arc::clone(&rw).read_owned().await; - /// assert_eq!(*v, 1); + /// let v = Arc::clone(&rw).read_owned().await; + /// assert_eq!(*v, 1); /// - /// assert!(rw.try_write_owned().is_err()); - /// } + /// assert!(rw.try_write_owned().is_err()); + /// # } /// ``` pub fn try_write_owned(self: Arc) -> Result, TryLockError> { match self.s.try_acquire(self.mr as usize) { diff --git a/tokio/src/sync/rwlock/owned_read_guard.rs b/tokio/src/sync/rwlock/owned_read_guard.rs index f50b2abc..019f6102 100644 --- a/tokio/src/sync/rwlock/owned_read_guard.rs +++ b/tokio/src/sync/rwlock/owned_read_guard.rs @@ -62,7 +62,7 @@ impl OwnedRwLockReadGuard { /// #[derive(Debug, Clone, Copy, PartialEq, Eq)] /// struct Foo(u32); /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let lock = Arc::new(RwLock::new(Foo(1))); /// @@ -109,7 +109,7 @@ impl OwnedRwLockReadGuard { /// #[derive(Debug, Clone, Copy, PartialEq, Eq)] /// struct Foo(u32); /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let lock = Arc::new(RwLock::new(Foo(1))); /// @@ -150,7 +150,7 @@ impl OwnedRwLockReadGuard { /// #[derive(Debug, Clone, Copy, PartialEq, Eq)] /// struct Foo(u32); /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let lock = Arc::new(RwLock::new(Foo(1))); /// diff --git a/tokio/src/sync/rwlock/owned_write_guard.rs b/tokio/src/sync/rwlock/owned_write_guard.rs index 11be26a9..7b34561b 100644 --- a/tokio/src/sync/rwlock/owned_write_guard.rs +++ b/tokio/src/sync/rwlock/owned_write_guard.rs @@ -69,7 +69,7 @@ impl OwnedRwLockWriteGuard { /// #[derive(Debug, Clone, Copy, PartialEq, Eq)] /// struct Foo(u32); /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let lock = Arc::new(RwLock::new(Foo(1))); /// @@ -121,7 +121,7 @@ impl OwnedRwLockWriteGuard { /// #[derive(Debug, Clone, Copy, PartialEq, Eq)] /// struct Foo(u32); /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let lock = Arc::new(RwLock::new(Foo(1))); /// @@ -193,7 +193,7 @@ impl OwnedRwLockWriteGuard { /// #[derive(Debug, Clone, Copy, PartialEq, Eq)] /// struct Foo(u32); /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let lock = Arc::new(RwLock::new(Foo(1))); /// @@ -255,7 +255,7 @@ impl OwnedRwLockWriteGuard { /// #[derive(Debug, Clone, Copy, PartialEq, Eq)] /// struct Foo(u32); /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let lock = Arc::new(RwLock::new(Foo(1))); /// @@ -337,7 +337,7 @@ impl OwnedRwLockWriteGuard { /// # use tokio::sync::RwLock; /// # use std::sync::Arc; /// # - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let lock = Arc::new(RwLock::new(1)); /// @@ -399,7 +399,7 @@ impl OwnedRwLockWriteGuard { /// use std::sync::Arc; /// use tokio::sync::{RwLock, OwnedRwLockWriteGuard}; /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let lock = Arc::new(RwLock::new(1)); /// diff --git a/tokio/src/sync/rwlock/owned_write_guard_mapped.rs b/tokio/src/sync/rwlock/owned_write_guard_mapped.rs index e0699d09..d8de3f8a 100644 --- a/tokio/src/sync/rwlock/owned_write_guard_mapped.rs +++ b/tokio/src/sync/rwlock/owned_write_guard_mapped.rs @@ -68,7 +68,7 @@ impl OwnedRwLockMappedWriteGuard { /// #[derive(Debug, Clone, Copy, PartialEq, Eq)] /// struct Foo(u32); /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let lock = Arc::new(RwLock::new(Foo(1))); /// @@ -119,7 +119,7 @@ impl OwnedRwLockMappedWriteGuard { /// #[derive(Debug, Clone, Copy, PartialEq, Eq)] /// struct Foo(u32); /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let lock = Arc::new(RwLock::new(Foo(1))); /// @@ -168,7 +168,7 @@ impl OwnedRwLockMappedWriteGuard { /// OwnedRwLockMappedWriteGuard, /// }; /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let lock = Arc::new(RwLock::new(1)); /// diff --git a/tokio/src/sync/rwlock/read_guard.rs b/tokio/src/sync/rwlock/read_guard.rs index a04b5958..a3a5ba82 100644 --- a/tokio/src/sync/rwlock/read_guard.rs +++ b/tokio/src/sync/rwlock/read_guard.rs @@ -66,7 +66,7 @@ impl<'a, T: ?Sized> RwLockReadGuard<'a, T> { /// #[derive(Debug, Clone, Copy, PartialEq, Eq)] /// struct Foo(u32); /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let lock = RwLock::new(Foo(1)); /// @@ -118,7 +118,7 @@ impl<'a, T: ?Sized> RwLockReadGuard<'a, T> { /// #[derive(Debug, Clone, Copy, PartialEq, Eq)] /// struct Foo(u32); /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let lock = RwLock::new(Foo(1)); /// diff --git a/tokio/src/sync/rwlock/write_guard.rs b/tokio/src/sync/rwlock/write_guard.rs index d405fc2b..766b26e0 100644 --- a/tokio/src/sync/rwlock/write_guard.rs +++ b/tokio/src/sync/rwlock/write_guard.rs @@ -72,7 +72,7 @@ impl<'a, T: ?Sized> RwLockWriteGuard<'a, T> { /// #[derive(Debug, Clone, Copy, PartialEq, Eq)] /// struct Foo(u32); /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let lock = RwLock::new(Foo(1)); /// @@ -130,7 +130,7 @@ impl<'a, T: ?Sized> RwLockWriteGuard<'a, T> { /// #[derive(Debug, Clone, Copy, PartialEq, Eq)] /// struct Foo(u32); /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let lock = RwLock::new(Foo(1)); /// @@ -205,7 +205,7 @@ impl<'a, T: ?Sized> RwLockWriteGuard<'a, T> { /// #[derive(Debug, Clone, Copy, PartialEq, Eq)] /// struct Foo(u32); /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let lock = RwLock::new(Foo(1)); /// @@ -274,7 +274,7 @@ impl<'a, T: ?Sized> RwLockWriteGuard<'a, T> { /// #[derive(Debug, Clone, Copy, PartialEq, Eq)] /// struct Foo(u32); /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let lock = RwLock::new(Foo(1)); /// @@ -352,7 +352,7 @@ impl<'a, T: ?Sized> RwLockWriteGuard<'a, T> { /// # use tokio::sync::RwLock; /// # use std::sync::Arc; /// # - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let lock = Arc::new(RwLock::new(1)); /// diff --git a/tokio/src/sync/rwlock/write_guard_mapped.rs b/tokio/src/sync/rwlock/write_guard_mapped.rs index 7705189e..dc67f255 100644 --- a/tokio/src/sync/rwlock/write_guard_mapped.rs +++ b/tokio/src/sync/rwlock/write_guard_mapped.rs @@ -69,7 +69,7 @@ impl<'a, T: ?Sized> RwLockMappedWriteGuard<'a, T> { /// #[derive(Debug, Clone, Copy, PartialEq, Eq)] /// struct Foo(u32); /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let lock = RwLock::new(Foo(1)); /// @@ -124,7 +124,7 @@ impl<'a, T: ?Sized> RwLockMappedWriteGuard<'a, T> { /// #[derive(Debug, Clone, Copy, PartialEq, Eq)] /// struct Foo(u32); /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// let lock = RwLock::new(Foo(1)); /// diff --git a/tokio/src/sync/semaphore.rs b/tokio/src/sync/semaphore.rs index 97963afd..8af5b54e 100644 --- a/tokio/src/sync/semaphore.rs +++ b/tokio/src/sync/semaphore.rs @@ -33,18 +33,18 @@ use std::sync::Arc; /// ``` /// use tokio::sync::{Semaphore, TryAcquireError}; /// -/// #[tokio::main] -/// async fn main() { -/// let semaphore = Semaphore::new(3); +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// let semaphore = Semaphore::new(3); /// -/// let a_permit = semaphore.acquire().await.unwrap(); -/// let two_permits = semaphore.acquire_many(2).await.unwrap(); +/// let a_permit = semaphore.acquire().await.unwrap(); +/// let two_permits = semaphore.acquire_many(2).await.unwrap(); /// -/// assert_eq!(semaphore.available_permits(), 0); +/// assert_eq!(semaphore.available_permits(), 0); /// -/// let permit_attempt = semaphore.try_acquire(); -/// assert_eq!(permit_attempt.err(), Some(TryAcquireError::NoPermits)); -/// } +/// let permit_attempt = semaphore.try_acquire(); +/// assert_eq!(permit_attempt.err(), Some(TryAcquireError::NoPermits)); +/// # } /// ``` /// /// ## Limit the number of simultaneously opened files in your program @@ -61,6 +61,8 @@ use std::sync::Arc; /// file, the program will wait until a permit becomes available before /// proceeding to open another file. /// ``` +/// # #[cfg(not(target_family = "wasm"))] +/// # { /// use std::io::Result; /// use tokio::fs::File; /// use tokio::sync::Semaphore; @@ -74,6 +76,7 @@ use std::sync::Arc; /// buffer.write_all(message).await?; /// Ok(()) // Permit goes out of scope here, and is available again for acquisition /// } +/// # } /// ``` /// /// ## Limit the number of outgoing requests being sent at the same time @@ -93,37 +96,37 @@ use std::sync::Arc; /// use std::sync::Arc; /// use tokio::sync::Semaphore; /// -/// #[tokio::main] -/// async fn main() { -/// // Define maximum number of parallel requests. -/// let semaphore = Arc::new(Semaphore::new(10)); -/// // Spawn many tasks that will send requests. -/// let mut jhs = Vec::new(); -/// for task_id in 0..100 { -/// let semaphore = semaphore.clone(); -/// let jh = tokio::spawn(async move { -/// // Acquire permit before sending request. -/// let _permit = semaphore.acquire().await.unwrap(); -/// // Send the request. -/// let response = send_request(task_id).await; -/// // Drop the permit after the request has been sent. -/// drop(_permit); -/// // Handle response. -/// // ... -/// -/// response -/// }); -/// jhs.push(jh); -/// } -/// // Collect responses from tasks. -/// let mut responses = Vec::new(); -/// for jh in jhs { -/// let response = jh.await.unwrap(); -/// responses.push(response); -/// } -/// // Process responses. -/// // ... +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// // Define maximum number of parallel requests. +/// let semaphore = Arc::new(Semaphore::new(5)); +/// // Spawn many tasks that will send requests. +/// let mut jhs = Vec::new(); +/// for task_id in 0..50 { +/// let semaphore = semaphore.clone(); +/// let jh = tokio::spawn(async move { +/// // Acquire permit before sending request. +/// let _permit = semaphore.acquire().await.unwrap(); +/// // Send the request. +/// let response = send_request(task_id).await; +/// // Drop the permit after the request has been sent. +/// drop(_permit); +/// // Handle response. +/// // ... +/// +/// response +/// }); +/// jhs.push(jh); /// } +/// // Collect responses from tasks. +/// let mut responses = Vec::new(); +/// for jh in jhs { +/// let response = jh.await.unwrap(); +/// responses.push(response); +/// } +/// // Process responses. +/// // ... +/// # } /// # async fn send_request(task_id: usize) { /// # // Send request. /// # } @@ -144,6 +147,8 @@ use std::sync::Arc; /// (Since our semaphore is not a global variable — if it was, then `acquire` would be enough.) /// /// ```no_run +/// # #[cfg(not(target_family = "wasm"))] +/// # { /// use std::sync::Arc; /// use tokio::sync::Semaphore; /// use tokio::net::TcpListener; @@ -174,6 +179,7 @@ use std::sync::Arc; /// # async fn handle_connection(_socket: &mut tokio::net::TcpStream) { /// # // Do work /// # } +/// # } /// ``` /// /// ## Prevent tests from running in parallel @@ -370,20 +376,20 @@ use std::sync::Arc; /// } /// } /// -/// #[tokio::main] +/// # #[tokio::main(flavor = "current_thread")] /// # async fn _hidden() {} /// # #[tokio::main(flavor = "current_thread", start_paused = true)] -/// async fn main() { -/// let capacity = 5; -/// let update_interval = Duration::from_secs_f32(1.0 / capacity as f32); -/// let bucket = TokenBucket::new(update_interval, capacity); +/// # async fn main() { +/// let capacity = 5; +/// let update_interval = Duration::from_secs_f32(1.0 / capacity as f32); +/// let bucket = TokenBucket::new(update_interval, capacity); /// -/// for _ in 0..5 { -/// bucket.acquire().await; +/// for _ in 0..5 { +/// bucket.acquire().await; /// -/// // do the operation -/// } +/// // do the operation /// } +/// # } /// ``` /// /// [`PollSemaphore`]: https://docs.rs/tokio-util/latest/tokio_util/sync/struct.PollSemaphore.html @@ -559,19 +565,19 @@ impl Semaphore { /// ``` /// use tokio::sync::Semaphore; /// - /// #[tokio::main] - /// async fn main() { - /// let semaphore = Semaphore::new(2); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let semaphore = Semaphore::new(2); /// - /// let permit_1 = semaphore.acquire().await.unwrap(); - /// assert_eq!(semaphore.available_permits(), 1); + /// let permit_1 = semaphore.acquire().await.unwrap(); + /// assert_eq!(semaphore.available_permits(), 1); /// - /// let permit_2 = semaphore.acquire().await.unwrap(); - /// assert_eq!(semaphore.available_permits(), 0); + /// let permit_2 = semaphore.acquire().await.unwrap(); + /// assert_eq!(semaphore.available_permits(), 0); /// - /// drop(permit_1); - /// assert_eq!(semaphore.available_permits(), 1); - /// } + /// drop(permit_1); + /// assert_eq!(semaphore.available_permits(), 1); + /// # } /// ``` /// /// [`AcquireError`]: crate::sync::AcquireError @@ -612,13 +618,13 @@ impl Semaphore { /// ``` /// use tokio::sync::Semaphore; /// - /// #[tokio::main] - /// async fn main() { - /// let semaphore = Semaphore::new(5); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let semaphore = Semaphore::new(5); /// - /// let permit = semaphore.acquire_many(3).await.unwrap(); - /// assert_eq!(semaphore.available_permits(), 2); - /// } + /// let permit = semaphore.acquire_many(3).await.unwrap(); + /// assert_eq!(semaphore.available_permits(), 2); + /// # } /// ``` /// /// [`AcquireError`]: crate::sync::AcquireError @@ -735,24 +741,24 @@ impl Semaphore { /// use std::sync::Arc; /// use tokio::sync::Semaphore; /// - /// #[tokio::main] - /// async fn main() { - /// let semaphore = Arc::new(Semaphore::new(3)); - /// let mut join_handles = Vec::new(); - /// - /// for _ in 0..5 { - /// let permit = semaphore.clone().acquire_owned().await.unwrap(); - /// join_handles.push(tokio::spawn(async move { - /// // perform task... - /// // explicitly own `permit` in the task - /// drop(permit); - /// })); - /// } - /// - /// for handle in join_handles { - /// handle.await.unwrap(); - /// } + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let semaphore = Arc::new(Semaphore::new(3)); + /// let mut join_handles = Vec::new(); + /// + /// for _ in 0..5 { + /// let permit = semaphore.clone().acquire_owned().await.unwrap(); + /// join_handles.push(tokio::spawn(async move { + /// // perform task... + /// // explicitly own `permit` in the task + /// drop(permit); + /// })); + /// } + /// + /// for handle in join_handles { + /// handle.await.unwrap(); /// } + /// # } /// ``` /// /// [`Arc`]: std::sync::Arc @@ -796,24 +802,24 @@ impl Semaphore { /// use std::sync::Arc; /// use tokio::sync::Semaphore; /// - /// #[tokio::main] - /// async fn main() { - /// let semaphore = Arc::new(Semaphore::new(10)); - /// let mut join_handles = Vec::new(); - /// - /// for _ in 0..5 { - /// let permit = semaphore.clone().acquire_many_owned(2).await.unwrap(); - /// join_handles.push(tokio::spawn(async move { - /// // perform task... - /// // explicitly own `permit` in the task - /// drop(permit); - /// })); - /// } - /// - /// for handle in join_handles { - /// handle.await.unwrap(); - /// } + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let semaphore = Arc::new(Semaphore::new(10)); + /// let mut join_handles = Vec::new(); + /// + /// for _ in 0..5 { + /// let permit = semaphore.clone().acquire_many_owned(2).await.unwrap(); + /// join_handles.push(tokio::spawn(async move { + /// // perform task... + /// // explicitly own `permit` in the task + /// drop(permit); + /// })); /// } + /// + /// for handle in join_handles { + /// handle.await.unwrap(); + /// } + /// # } /// ``` /// /// [`Arc`]: std::sync::Arc @@ -936,23 +942,23 @@ impl Semaphore { /// use std::sync::Arc; /// use tokio::sync::TryAcquireError; /// - /// #[tokio::main] - /// async fn main() { - /// let semaphore = Arc::new(Semaphore::new(1)); - /// let semaphore2 = semaphore.clone(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let semaphore = Arc::new(Semaphore::new(1)); + /// let semaphore2 = semaphore.clone(); /// - /// tokio::spawn(async move { - /// let permit = semaphore.acquire_many(2).await; - /// assert!(permit.is_err()); - /// println!("waiter received error"); - /// }); + /// tokio::spawn(async move { + /// let permit = semaphore.acquire_many(2).await; + /// assert!(permit.is_err()); + /// println!("waiter received error"); + /// }); /// - /// println!("closing semaphore"); - /// semaphore2.close(); + /// println!("closing semaphore"); + /// semaphore2.close(); /// - /// // Cannot obtain more permits - /// assert_eq!(semaphore2.try_acquire().err(), Some(TryAcquireError::Closed)) - /// } + /// // Cannot obtain more permits + /// assert_eq!(semaphore2.try_acquire().err(), Some(TryAcquireError::Closed)) + /// # } /// ``` pub fn close(&self) { self.ll_sem.close(); diff --git a/tokio/src/sync/set_once.rs b/tokio/src/sync/set_once.rs index 3170a9cd..3c4228e6 100644 --- a/tokio/src/sync/set_once.rs +++ b/tokio/src/sync/set_once.rs @@ -35,20 +35,20 @@ use std::task::Poll; /// /// static ONCE: SetOnce = SetOnce::const_new(); /// -/// #[tokio::main] -/// async fn main() -> Result<(), SetOnceError> { +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() -> Result<(), SetOnceError> { /// -/// // set the value inside a task somewhere... -/// tokio::spawn(async move { ONCE.set(20) }); +/// // set the value inside a task somewhere... +/// tokio::spawn(async move { ONCE.set(20) }); /// -/// // checking with .get doesn't block main thread -/// println!("{:?}", ONCE.get()); +/// // checking with .get doesn't block main thread +/// println!("{:?}", ONCE.get()); /// -/// // wait until the value is set, blocks the thread -/// println!("{:?}", ONCE.wait().await); +/// // wait until the value is set, blocks the thread +/// println!("{:?}", ONCE.wait().await); /// -/// Ok(()) -/// } +/// Ok(()) +/// # } /// ``` /// /// A `SetOnce` is typically used for global variables that need to be @@ -61,30 +61,30 @@ use std::task::Poll; /// use tokio::sync::{SetOnce, SetOnceError}; /// use std::sync::Arc; /// -/// #[tokio::main] -/// async fn main() -> Result<(), SetOnceError> { -/// let once = SetOnce::new(); +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() -> Result<(), SetOnceError> { +/// let once = SetOnce::new(); /// -/// let arc = Arc::new(once); -/// let first_cl = Arc::clone(&arc); -/// let second_cl = Arc::clone(&arc); +/// let arc = Arc::new(once); +/// let first_cl = Arc::clone(&arc); +/// let second_cl = Arc::clone(&arc); /// -/// // set the value inside a task -/// tokio::spawn(async move { first_cl.set(20) }).await.unwrap()?; +/// // set the value inside a task +/// tokio::spawn(async move { first_cl.set(20) }).await.unwrap()?; /// -/// // wait inside task to not block the main thread -/// tokio::spawn(async move { -/// // wait inside async context for the value to be set -/// assert_eq!(*second_cl.wait().await, 20); -/// }).await.unwrap(); +/// // wait inside task to not block the main thread +/// tokio::spawn(async move { +/// // wait inside async context for the value to be set +/// assert_eq!(*second_cl.wait().await, 20); +/// }).await.unwrap(); /// -/// // subsequent set calls will fail -/// assert!(arc.set(30).is_err()); +/// // subsequent set calls will fail +/// assert!(arc.set(30).is_err()); /// -/// println!("{:?}", arc.get()); +/// println!("{:?}", arc.get()); /// -/// Ok(()) -/// } +/// Ok(()) +/// # } /// ``` /// /// [`asyncio.Event`]: https://docs.python.org/3/library/asyncio-sync.html#asyncio.Event @@ -175,13 +175,13 @@ impl SetOnce { /// Ok(ONCE.get()) /// } /// - /// #[tokio::main] - /// async fn main() -> Result<(), SetOnceError> { - /// let result = get_global_integer()?; + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() -> Result<(), SetOnceError> { + /// let result = get_global_integer()?; /// - /// assert_eq!(result, Some(&2)); - /// Ok(()) - /// } + /// assert_eq!(result, Some(&2)); + /// Ok(()) + /// # } /// ``` /// /// [`tokio-console`]: https://github.com/tokio-rs/console @@ -226,12 +226,12 @@ impl SetOnce { /// ONCE.get() /// } /// - /// #[tokio::main] - /// async fn main() { - /// let result = get_global_integer(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let result = get_global_integer(); /// - /// assert_eq!(result, Some(&1)); - /// } + /// assert_eq!(result, Some(&1)); + /// # } /// ``` /// /// [`tokio-console`]: https://github.com/tokio-rs/console diff --git a/tokio/src/sync/watch.rs b/tokio/src/sync/watch.rs index 6ffa53c7..7a8a994f 100644 --- a/tokio/src/sync/watch.rs +++ b/tokio/src/sync/watch.rs @@ -111,25 +111,25 @@ //! ``` //! use tokio::sync::watch; //! -//! #[tokio::main] -//! async fn main() { -//! let (tx, mut rx) = watch::channel("hello"); -//! tx.send("goodbye").unwrap(); -//! drop(tx); +//! #[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()); +//! // `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()); +//! // `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()); -//! } +//! // 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 @@ -258,35 +258,35 @@ impl<'a, T> Ref<'a, T> { /// ``` /// use tokio::sync::watch; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = watch::channel("hello"); - /// - /// tx.send("goodbye").unwrap(); - /// // The sender does never consider the value as changed. - /// assert!(!tx.borrow().has_changed()); - /// - /// // Drop the sender immediately, just for testing purposes. - /// drop(tx); - /// - /// // Even if the sender has already been dropped... - /// assert!(rx.has_changed().is_err()); - /// // ...the modified value is still readable and detected as changed. - /// assert_eq!(*rx.borrow(), "goodbye"); - /// assert!(rx.borrow().has_changed()); - /// - /// // Read the changed value and mark it as seen. - /// { - /// let received = rx.borrow_and_update(); - /// assert_eq!(*received, "goodbye"); - /// assert!(received.has_changed()); - /// // Release the read lock when leaving this scope. - /// } - /// - /// // Now the value has already been marked as seen and could - /// // never be modified again (after the sender has been dropped). - /// assert!(!rx.borrow().has_changed()); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = watch::channel("hello"); + /// + /// tx.send("goodbye").unwrap(); + /// // The sender does never consider the value as changed. + /// assert!(!tx.borrow().has_changed()); + /// + /// // Drop the sender immediately, just for testing purposes. + /// drop(tx); + /// + /// // Even if the sender has already been dropped... + /// assert!(rx.has_changed().is_err()); + /// // ...the modified value is still readable and detected as changed. + /// assert_eq!(*rx.borrow(), "goodbye"); + /// assert!(rx.borrow().has_changed()); + /// + /// // Read the changed value and mark it as seen. + /// { + /// let received = rx.borrow_and_update(); + /// assert_eq!(*received, "goodbye"); + /// assert!(received.has_changed()); + /// // Release the read lock when leaving this scope. /// } + /// + /// // Now the value has already been marked as seen and could + /// // never be modified again (after the sender has been dropped). + /// assert!(!rx.borrow().has_changed()); + /// # } /// ``` pub fn has_changed(&self) -> bool { self.has_changed @@ -705,18 +705,18 @@ impl Receiver { /// ``` /// use tokio::sync::watch; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = watch::channel("hello"); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = watch::channel("hello"); /// - /// tx.send("goodbye").unwrap(); + /// tx.send("goodbye").unwrap(); /// - /// assert!(rx.has_changed().unwrap()); - /// assert_eq!(*rx.borrow_and_update(), "goodbye"); + /// assert!(rx.has_changed().unwrap()); + /// assert_eq!(*rx.borrow_and_update(), "goodbye"); /// - /// // The value has been marked as seen - /// assert!(!rx.has_changed().unwrap()); - /// } + /// // The value has been marked as seen + /// assert!(!rx.has_changed().unwrap()); + /// # } /// ``` /// /// ## Closed channel example @@ -724,16 +724,16 @@ impl Receiver { /// ``` /// use tokio::sync::watch; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, rx) = watch::channel("hello"); - /// tx.send("goodbye").unwrap(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, rx) = watch::channel("hello"); + /// tx.send("goodbye").unwrap(); /// - /// drop(tx); + /// drop(tx); /// - /// // The channel is closed - /// assert!(rx.has_changed().is_err()); - /// } + /// // The channel is closed + /// assert!(rx.has_changed().is_err()); + /// # } /// ``` pub fn has_changed(&self) -> Result { // Load the version from the state @@ -800,20 +800,20 @@ impl Receiver { /// ``` /// use tokio::sync::watch; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, mut rx) = watch::channel("hello"); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, mut rx) = watch::channel("hello"); /// - /// tokio::spawn(async move { - /// tx.send("goodbye").unwrap(); - /// }); + /// tokio::spawn(async move { + /// tx.send("goodbye").unwrap(); + /// }); /// - /// assert!(rx.changed().await.is_ok()); - /// assert_eq!(*rx.borrow_and_update(), "goodbye"); + /// assert!(rx.changed().await.is_ok()); + /// assert_eq!(*rx.borrow_and_update(), "goodbye"); /// - /// // The `tx` handle has been dropped - /// assert!(rx.changed().await.is_err()); - /// } + /// // The `tx` handle has been dropped + /// assert!(rx.changed().await.is_err()); + /// # } /// ``` pub async fn changed(&mut self) -> Result<(), error::RecvError> { cooperative(changed_impl(&self.shared, &mut self.version)).await @@ -1296,19 +1296,19 @@ impl Sender { /// ``` /// use tokio::sync::watch; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, rx) = watch::channel("hello"); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, rx) = watch::channel("hello"); /// - /// tokio::spawn(async move { - /// // use `rx` - /// drop(rx); - /// }); + /// tokio::spawn(async move { + /// // use `rx` + /// drop(rx); + /// }); /// - /// // Waits for `rx` to drop - /// tx.closed().await; - /// println!("the `rx` handles dropped") - /// } + /// // Waits for `rx` to drop + /// tx.closed().await; + /// println!("the `rx` handles dropped") + /// # } /// ``` pub async fn closed(&self) { cooperative(async { @@ -1344,18 +1344,18 @@ impl Sender { /// ``` /// use tokio::sync::watch; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, _rx) = watch::channel(0u64); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, _rx) = watch::channel(0u64); /// - /// tx.send(5).unwrap(); + /// tx.send(5).unwrap(); /// - /// let rx = tx.subscribe(); - /// assert_eq!(5, *rx.borrow()); + /// let rx = tx.subscribe(); + /// assert_eq!(5, *rx.borrow()); /// - /// tx.send(10).unwrap(); - /// assert_eq!(10, *rx.borrow()); - /// } + /// tx.send(10).unwrap(); + /// assert_eq!(10, *rx.borrow()); + /// # } /// ``` /// /// The most recent message is considered seen by the channel, so this test @@ -1365,24 +1365,24 @@ impl Sender { /// use tokio::sync::watch; /// use tokio::time::Duration; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, _rx) = watch::channel(0u64); - /// tx.send(5).unwrap(); - /// let mut rx = tx.subscribe(); - /// - /// tokio::spawn(async move { - /// // by spawning and sleeping, the message is sent after `main` - /// // hits the call to `changed`. - /// # if false { - /// tokio::time::sleep(Duration::from_millis(10)).await; - /// # } - /// tx.send(100).unwrap(); - /// }); - /// - /// rx.changed().await.unwrap(); - /// assert_eq!(100, *rx.borrow()); - /// } + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, _rx) = watch::channel(0u64); + /// tx.send(5).unwrap(); + /// let mut rx = tx.subscribe(); + /// + /// tokio::spawn(async move { + /// // by spawning and sleeping, the message is sent after `main` + /// // hits the call to `changed`. + /// # if false { + /// tokio::time::sleep(Duration::from_millis(10)).await; + /// # } + /// tx.send(100).unwrap(); + /// }); + /// + /// rx.changed().await.unwrap(); + /// assert_eq!(100, *rx.borrow()); + /// # } /// ``` pub fn subscribe(&self) -> Receiver { let shared = self.shared.clone(); @@ -1400,16 +1400,16 @@ impl Sender { /// ``` /// use tokio::sync::watch; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx, rx1) = watch::channel("hello"); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx, rx1) = watch::channel("hello"); /// - /// assert_eq!(1, tx.receiver_count()); + /// assert_eq!(1, tx.receiver_count()); /// - /// let mut _rx2 = rx1.clone(); + /// let mut _rx2 = rx1.clone(); /// - /// assert_eq!(2, tx.receiver_count()); - /// } + /// assert_eq!(2, tx.receiver_count()); + /// # } /// ``` pub fn receiver_count(&self) -> usize { self.shared.ref_count_rx.load(Relaxed) @@ -1422,17 +1422,17 @@ impl Sender { /// ``` /// use tokio::sync::watch; /// - /// #[tokio::main] - /// async fn main() { - /// let (tx1, rx) = watch::channel("hello"); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let (tx1, rx) = watch::channel("hello"); /// - /// assert_eq!(1, tx1.sender_count()); + /// assert_eq!(1, tx1.sender_count()); /// - /// let tx2 = tx1.clone(); + /// let tx2 = tx1.clone(); /// - /// assert_eq!(2, tx1.sender_count()); - /// assert_eq!(2, tx2.sender_count()); - /// } + /// assert_eq!(2, tx1.sender_count()); + /// assert_eq!(2, tx2.sender_count()); + /// # } /// ``` pub fn sender_count(&self) -> usize { self.shared.ref_count_tx.load(Relaxed) diff --git a/tokio/src/task/coop/mod.rs b/tokio/src/task/coop/mod.rs index 70cf6ea9..4a520e6f 100644 --- a/tokio/src/task/coop/mod.rs +++ b/tokio/src/task/coop/mod.rs @@ -37,7 +37,7 @@ //! Tokio. For example: //! //! ``` -//! # #[tokio::main] +//! # #[tokio::main(flavor = "current_thread")] //! # async fn main() { //! use tokio::{task, sync::mpsc}; //! diff --git a/tokio/src/task/join_set.rs b/tokio/src/task/join_set.rs index 1f8fc6a4..cb5470e6 100644 --- a/tokio/src/task/join_set.rs +++ b/tokio/src/task/join_set.rs @@ -31,24 +31,24 @@ use crate::util::IdleNotifiedSet; /// ``` /// use tokio::task::JoinSet; /// -/// #[tokio::main] -/// async fn main() { -/// let mut set = JoinSet::new(); +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// let mut set = JoinSet::new(); /// -/// for i in 0..10 { -/// set.spawn(async move { i }); -/// } +/// 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; -/// } +/// 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]); -/// } +/// for i in 0..10 { +/// assert!(seen[i]); /// } +/// # } /// ``` /// /// # Task ID guarantees @@ -219,6 +219,8 @@ impl JoinSet { /// Spawn multiple blocking tasks and wait for them. /// /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::task::JoinSet; /// /// #[tokio::main] @@ -239,6 +241,7 @@ impl JoinSet { /// assert!(seen[i]); /// } /// } + /// # } /// ``` /// /// # Panics @@ -396,20 +399,20 @@ impl JoinSet { /// use tokio::task::JoinSet; /// use std::time::Duration; /// - /// #[tokio::main] - /// async fn main() { - /// let mut set = JoinSet::new(); - /// - /// for i in 0..3 { - /// set.spawn(async move { - /// tokio::time::sleep(Duration::from_secs(3 - i)).await; - /// i - /// }); - /// } + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let mut set = JoinSet::new(); /// - /// let output = set.join_all().await; - /// assert_eq!(output, vec![2, 1, 0]); + /// for i in 0..3 { + /// set.spawn(async move { + /// tokio::time::sleep(Duration::from_secs(3 - i)).await; + /// i + /// }); /// } + /// + /// let output = set.join_all().await; + /// assert_eq!(output, vec![2, 1, 0]); + /// # } /// ``` /// /// Equivalent implementation of `join_all`, using [`join_next`] and loop. @@ -418,24 +421,24 @@ impl JoinSet { /// use tokio::task::JoinSet; /// use std::panic; /// - /// #[tokio::main] - /// async fn main() { - /// let mut set = JoinSet::new(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let mut set = JoinSet::new(); /// - /// for i in 0..3 { - /// set.spawn(async move {i}); - /// } + /// for i in 0..3 { + /// set.spawn(async move {i}); + /// } /// - /// let mut output = Vec::new(); - /// while let Some(res) = set.join_next().await{ - /// match res { - /// Ok(t) => output.push(t), - /// Err(err) if err.is_panic() => panic::resume_unwind(err.into_panic()), - /// Err(err) => panic!("{err}"), - /// } + /// let mut output = Vec::new(); + /// while let Some(res) = set.join_next().await{ + /// match res { + /// Ok(t) => output.push(t), + /// Err(err) if err.is_panic() => panic::resume_unwind(err.into_panic()), + /// Err(err) => panic!("{err}"), /// } - /// assert_eq!(output.len(),3); /// } + /// assert_eq!(output.len(),3); + /// # } /// ``` /// [`join_next`]: fn@Self::join_next /// [`JoinError::id`]: fn@crate::task::JoinError::id @@ -613,20 +616,20 @@ impl Default for JoinSet { /// ``` /// use tokio::task::JoinSet; /// -/// #[tokio::main] -/// async fn main() { -/// let mut set: JoinSet<_> = (0..10).map(|i| async move { i }).collect(); +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// let mut set: JoinSet<_> = (0..10).map(|i| async move { i }).collect(); /// -/// let mut seen = [false; 10]; -/// while let Some(res) = set.join_next().await { -/// let idx = res.unwrap(); -/// seen[idx] = true; -/// } +/// 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]); -/// } +/// for i in 0..10 { +/// assert!(seen[i]); /// } +/// # } /// ``` /// /// [`collect`]: std::iter::Iterator::collect diff --git a/tokio/src/task/local.rs b/tokio/src/task/local.rs index 22b1b9bb..40f16053 100644 --- a/tokio/src/task/local.rs +++ b/tokio/src/task/local.rs @@ -64,24 +64,24 @@ cfg_rt! { /// use std::rc::Rc; /// use tokio::task; /// - /// #[tokio::main] - /// async fn main() { - /// let nonsend_data = Rc::new("my nonsend data..."); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let nonsend_data = Rc::new("my nonsend data..."); /// - /// // Construct a local task set that can run `!Send` futures. - /// let local = task::LocalSet::new(); + /// // Construct a local task set that can run `!Send` futures. + /// let local = task::LocalSet::new(); /// - /// // Run the local task set. - /// local.run_until(async move { - /// let nonsend_data = nonsend_data.clone(); - /// // `spawn_local` ensures that the future is spawned on the local - /// // task set. - /// task::spawn_local(async move { - /// println!("{}", nonsend_data); - /// // ... - /// }).await.unwrap(); - /// }).await; - /// } + /// // Run the local task set. + /// local.run_until(async move { + /// let nonsend_data = nonsend_data.clone(); + /// // `spawn_local` ensures that the future is spawned on the local + /// // task set. + /// task::spawn_local(async move { + /// println!("{}", nonsend_data); + /// // ... + /// }).await.unwrap(); + /// }).await; + /// # } /// ``` /// **Note:** The `run_until` method can only be used in `#[tokio::main]`, /// `#[tokio::test]` or directly inside a call to [`Runtime::block_on`]. It @@ -98,26 +98,26 @@ cfg_rt! { /// use tokio::{task, time}; /// use std::rc::Rc; /// - /// #[tokio::main] - /// async fn main() { - /// let nonsend_data = Rc::new("world"); - /// let local = task::LocalSet::new(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let nonsend_data = Rc::new("world"); + /// let local = task::LocalSet::new(); /// - /// let nonsend_data2 = nonsend_data.clone(); - /// local.spawn_local(async move { - /// // ... - /// println!("hello {}", nonsend_data2) - /// }); + /// let nonsend_data2 = nonsend_data.clone(); + /// local.spawn_local(async move { + /// // ... + /// println!("hello {}", nonsend_data2) + /// }); /// - /// local.spawn_local(async move { - /// time::sleep(time::Duration::from_millis(100)).await; - /// println!("goodbye {}", nonsend_data) - /// }); + /// local.spawn_local(async move { + /// time::sleep(time::Duration::from_millis(100)).await; + /// println!("goodbye {}", nonsend_data) + /// }); /// - /// // ... + /// // ... /// - /// local.await; - /// } + /// local.await; + /// # } /// ``` /// **Note:** Awaiting a `LocalSet` can only be done inside /// `#[tokio::main]`, `#[tokio::test]` or directly inside a call to @@ -133,6 +133,8 @@ cfg_rt! { /// /// The following example puts the `LocalSet` inside a new thread. /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime::Builder; /// use tokio::sync::{mpsc, oneshot}; /// use tokio::task::LocalSet; @@ -212,6 +214,7 @@ cfg_rt! { /// let eleven = response.await.unwrap(); /// assert_eq!(eleven, 11); /// } + /// # } /// ``` /// /// [`Send`]: trait@std::marker::Send @@ -354,21 +357,21 @@ cfg_rt! { /// use std::rc::Rc; /// use tokio::task; /// - /// #[tokio::main] - /// async fn main() { - /// let nonsend_data = Rc::new("my nonsend data..."); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let nonsend_data = Rc::new("my nonsend data..."); /// - /// let local = task::LocalSet::new(); + /// let local = task::LocalSet::new(); /// - /// // Run the local task set. - /// local.run_until(async move { - /// let nonsend_data = nonsend_data.clone(); - /// task::spawn_local(async move { - /// println!("{}", nonsend_data); - /// // ... - /// }).await.unwrap(); - /// }).await; - /// } + /// // Run the local task set. + /// local.run_until(async move { + /// let nonsend_data = nonsend_data.clone(); + /// task::spawn_local(async move { + /// println!("{}", nonsend_data); + /// // ... + /// }).await.unwrap(); + /// }).await; + /// # } /// ``` /// /// [`LocalSet`]: struct@crate::task::LocalSet @@ -543,31 +546,31 @@ impl LocalSet { /// ```rust /// use tokio::task; /// - /// #[tokio::main] - /// async fn main() { - /// let local = task::LocalSet::new(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let local = task::LocalSet::new(); /// - /// // Spawn a future on the local set. This future will be run when - /// // we call `run_until` to drive the task set. - /// local.spawn_local(async { - /// // ... - /// }); + /// // Spawn a future on the local set. This future will be run when + /// // we call `run_until` to drive the task set. + /// local.spawn_local(async { + /// // ... + /// }); /// - /// // Run the local task set. - /// local.run_until(async move { - /// // ... - /// }).await; + /// // Run the local task set. + /// local.run_until(async move { + /// // ... + /// }).await; /// - /// // When `run` finishes, we can spawn _more_ futures, which will - /// // run in subsequent calls to `run_until`. - /// local.spawn_local(async { - /// // ... - /// }); + /// // When `run` finishes, we can spawn _more_ futures, which will + /// // run in subsequent calls to `run_until`. + /// local.spawn_local(async { + /// // ... + /// }); /// - /// local.run_until(async move { - /// // ... - /// }).await; - /// } + /// local.run_until(async move { + /// // ... + /// }).await; + /// # } /// ``` /// [`spawn_local`]: fn@spawn_local #[track_caller] @@ -608,7 +611,7 @@ impl LocalSet { /// issued from a local task, the [`spawn_blocking`] API may be used instead. /// /// For example, this will panic: - /// ```should_panic + /// ```should_panic,ignore-wasm /// use tokio::runtime::Runtime; /// use tokio::task; /// @@ -626,6 +629,8 @@ impl LocalSet { /// ``` /// This, however, will not panic: /// ``` + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::runtime::Runtime; /// use tokio::task; /// @@ -640,6 +645,7 @@ impl LocalSet { /// }); /// join.await.unwrap(); /// }) + /// # } /// ``` /// /// [`spawn_local`]: fn@spawn_local @@ -675,15 +681,15 @@ impl LocalSet { /// ```rust /// use tokio::task; /// - /// #[tokio::main] - /// async fn main() { - /// task::LocalSet::new().run_until(async { - /// task::spawn_local(async move { - /// // ... - /// }).await.unwrap(); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// task::LocalSet::new().run_until(async { + /// task::spawn_local(async move { /// // ... - /// }).await; - /// } + /// }).await.unwrap(); + /// // ... + /// }).await; + /// # } /// ``` /// /// [`spawn_local`]: fn@spawn_local @@ -863,7 +869,7 @@ cfg_unstable! { /// ```should_panic /// use tokio::runtime::UnhandledPanic; /// - /// # #[tokio::main] + /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { /// tokio::task::LocalSet::new() /// .unhandled_panic(UnhandledPanic::ShutdownRuntime) @@ -897,11 +903,11 @@ cfg_unstable! { /// ```rust /// use tokio::task; /// - /// #[tokio::main] - /// async fn main() { - /// let local_set = task::LocalSet::new(); - /// println!("Local set id: {}", local_set.id()); - /// } + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let local_set = task::LocalSet::new(); + /// println!("Local set id: {}", local_set.id()); + /// # } /// ``` /// /// **Note**: This is an [unstable API][unstable]. The public API of this type diff --git a/tokio/src/task/mod.rs b/tokio/src/task/mod.rs index f0c6f71c..ebd3a1bc 100644 --- a/tokio/src/task/mod.rs +++ b/tokio/src/task/mod.rs @@ -70,7 +70,8 @@ //! ``` //! use tokio::task; //! -//! # #[tokio::main] async fn main() -> Result<(), Box> { +//! # #[tokio::main(flavor = "current_thread")] +//! # async fn main() -> Result<(), Box> { //! let join = task::spawn(async { //! // ... //! "hello world!" @@ -90,6 +91,8 @@ //! example: //! //! ``` +//! # #[cfg(not(target_family = "wasm"))] +//! # { //! use tokio::task; //! //! # #[tokio::main] async fn main() { @@ -100,6 +103,7 @@ //! // The returned result indicates that the task failed. //! assert!(join.await.is_err()); //! # } +//! # } //! ``` //! //! `spawn`, `JoinHandle`, and `JoinError` are present when the "rt" @@ -221,6 +225,8 @@ //! For example: //! //! ``` +//! # #[cfg(not(target_family = "wasm"))] +//! # { //! use tokio::task; //! //! # async fn docs() { @@ -231,6 +237,7 @@ //! //! assert_eq!(result, "blocking completed"); //! # } +//! # } //! ``` //! //! #### `yield_now` @@ -245,7 +252,8 @@ //! ```rust //! use tokio::task; //! -//! # #[tokio::main] async fn main() { +//! # #[tokio::main(flavor = "current_thread")] +//! # async fn main() { //! async { //! task::spawn(async { //! // ... diff --git a/tokio/src/task/spawn.rs b/tokio/src/task/spawn.rs index ab9bf549..1b219a28 100644 --- a/tokio/src/task/spawn.rs +++ b/tokio/src/task/spawn.rs @@ -35,6 +35,8 @@ cfg_rt! { /// that processes each received connection. /// /// ```no_run + /// # #[cfg(not(target_family = "wasm"))] + /// # { /// use tokio::net::{TcpListener, TcpStream}; /// /// use std::io; @@ -57,6 +59,7 @@ cfg_rt! { /// }); /// } /// } + /// # } /// ``` /// /// To run multiple tasks in parallel and receive their results, join @@ -112,18 +115,18 @@ cfg_rt! { /// # drop(rc); /// } /// - /// #[tokio::main] - /// async fn main() { - /// tokio::spawn(async { - /// // Force the `Rc` to stay in a scope with no `.await` - /// { - /// let rc = Rc::new(()); - /// use_rc(rc.clone()); - /// } + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// tokio::spawn(async { + /// // Force the `Rc` to stay in a scope with no `.await` + /// { + /// let rc = Rc::new(()); + /// use_rc(rc.clone()); + /// } /// - /// task::yield_now().await; - /// }).await.unwrap(); - /// } + /// task::yield_now().await; + /// }).await.unwrap(); + /// # } /// ``` /// /// This will **not** work: diff --git a/tokio/src/time/instant.rs b/tokio/src/time/instant.rs index 44955dc9..faf62ee5 100644 --- a/tokio/src/time/instant.rs +++ b/tokio/src/time/instant.rs @@ -81,14 +81,14 @@ impl Instant { /// ``` /// use tokio::time::{Duration, Instant, sleep}; /// - /// #[tokio::main] - /// async fn main() { - /// let now = Instant::now(); - /// sleep(Duration::new(1, 0)).await; - /// let new_now = Instant::now(); - /// println!("{:?}", new_now.checked_duration_since(now)); - /// println!("{:?}", now.checked_duration_since(new_now)); // None - /// } + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let now = Instant::now(); + /// sleep(Duration::new(1, 0)).await; + /// let new_now = Instant::now(); + /// println!("{:?}", new_now.checked_duration_since(now)); + /// println!("{:?}", now.checked_duration_since(new_now)); // None + /// # } /// ``` pub fn checked_duration_since(&self, earlier: Instant) -> Option { self.std.checked_duration_since(earlier.std) @@ -102,13 +102,13 @@ impl Instant { /// ``` /// use tokio::time::{Duration, Instant, sleep}; /// - /// #[tokio::main] - /// async fn main() { - /// let now = Instant::now(); - /// sleep(Duration::new(1, 0)).await; - /// let new_now = Instant::now(); - /// println!("{:?}", new_now.saturating_duration_since(now)); - /// println!("{:?}", now.saturating_duration_since(new_now)); // 0ns + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let now = Instant::now(); + /// sleep(Duration::new(1, 0)).await; + /// let new_now = Instant::now(); + /// println!("{:?}", new_now.saturating_duration_since(now)); + /// println!("{:?}", now.saturating_duration_since(new_now)); // 0ns /// } /// ``` pub fn saturating_duration_since(&self, earlier: Instant) -> Duration { @@ -123,13 +123,13 @@ impl Instant { /// ``` /// use tokio::time::{Duration, Instant, sleep}; /// - /// #[tokio::main] - /// async fn main() { - /// let instant = Instant::now(); - /// let three_secs = Duration::from_secs(3); - /// sleep(three_secs).await; - /// assert!(instant.elapsed() >= three_secs); - /// } + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let instant = Instant::now(); + /// let three_secs = Duration::from_secs(3); + /// sleep(three_secs).await; + /// assert!(instant.elapsed() >= three_secs); + /// # } /// ``` pub fn elapsed(&self) -> Duration { Instant::now().saturating_duration_since(*self) diff --git a/tokio/src/time/interval.rs b/tokio/src/time/interval.rs index 0153a567..02cecc6e 100644 --- a/tokio/src/time/interval.rs +++ b/tokio/src/time/interval.rs @@ -26,16 +26,16 @@ use std::task::{ready, Context, Poll}; /// ``` /// use tokio::time::{self, Duration}; /// -/// #[tokio::main] -/// async fn main() { -/// let mut interval = time::interval(Duration::from_millis(10)); +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// let mut interval = time::interval(Duration::from_millis(10)); /// -/// interval.tick().await; // ticks immediately -/// interval.tick().await; // ticks after 10ms -/// interval.tick().await; // ticks after 10ms +/// interval.tick().await; // ticks immediately +/// interval.tick().await; // ticks after 10ms +/// interval.tick().await; // ticks after 10ms /// -/// // approximately 20ms have elapsed. -/// } +/// // approximately 20ms have elapsed. +/// # } /// ``` /// /// A simple example using `interval` to execute a task every two seconds. @@ -57,14 +57,14 @@ use std::task::{ready, Context, Poll}; /// time::sleep(time::Duration::from_secs(1)).await /// } /// -/// #[tokio::main] -/// 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; -/// } +/// # #[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; /// } +/// # } /// ``` /// /// [`sleep`]: crate::time::sleep() @@ -92,17 +92,17 @@ pub fn interval(period: Duration) -> Interval { /// ``` /// use tokio::time::{interval_at, Duration, Instant}; /// -/// #[tokio::main] -/// async fn main() { -/// let start = Instant::now() + Duration::from_millis(50); -/// let mut interval = interval_at(start, Duration::from_millis(10)); +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// let start = Instant::now() + Duration::from_millis(50); +/// let mut interval = interval_at(start, Duration::from_millis(10)); /// -/// interval.tick().await; // ticks after 50ms -/// interval.tick().await; // ticks after 10ms -/// interval.tick().await; // ticks after 10ms +/// interval.tick().await; // ticks after 50ms +/// interval.tick().await; // ticks after 10ms +/// interval.tick().await; // ticks after 10ms /// -/// // approximately 70ms have elapsed. -/// } +/// // approximately 70ms have elapsed. +/// # } /// ``` #[track_caller] pub fn interval_at(start: Instant, period: Duration) -> Interval { @@ -155,16 +155,16 @@ fn internal_interval_at( /// use tokio::time::{self, Duration}; /// # async fn task_that_takes_one_to_three_millis() {} /// -/// #[tokio::main] -/// async fn main() { -/// // ticks every 2 milliseconds -/// let mut interval = time::interval(Duration::from_millis(2)); -/// for _ in 0..5 { -/// interval.tick().await; -/// // if this takes more than 2 milliseconds, a tick will be delayed -/// task_that_takes_one_to_three_millis().await; -/// } +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// // ticks every 2 milliseconds +/// let mut interval = time::interval(Duration::from_millis(2)); +/// for _ in 0..5 { +/// interval.tick().await; +/// // if this takes more than 2 milliseconds, a tick will be delayed +/// task_that_takes_one_to_three_millis().await; /// } +/// # } /// ``` /// /// Generally, a tick is missed if too much time is spent without calling @@ -418,17 +418,17 @@ impl Interval { /// /// use std::time::Duration; /// - /// #[tokio::main] - /// async fn main() { - /// let mut interval = time::interval(Duration::from_millis(10)); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let mut interval = time::interval(Duration::from_millis(10)); /// - /// interval.tick().await; - /// // approximately 0ms have elapsed. The first tick completes immediately. - /// interval.tick().await; - /// interval.tick().await; + /// interval.tick().await; + /// // approximately 0ms have elapsed. The first tick completes immediately. + /// interval.tick().await; + /// interval.tick().await; /// - /// // approximately 20ms have elapsed. - /// } + /// // approximately 20ms have elapsed. + /// # } /// ``` pub async fn tick(&mut self) -> Instant { #[cfg(all(tokio_unstable, feature = "tracing"))] @@ -506,20 +506,20 @@ impl Interval { /// /// use std::time::Duration; /// - /// #[tokio::main] - /// async fn main() { - /// let mut interval = time::interval(Duration::from_millis(100)); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let mut interval = time::interval(Duration::from_millis(100)); /// - /// interval.tick().await; + /// interval.tick().await; /// - /// time::sleep(Duration::from_millis(50)).await; - /// interval.reset(); + /// time::sleep(Duration::from_millis(50)).await; + /// interval.reset(); /// - /// interval.tick().await; - /// interval.tick().await; + /// interval.tick().await; + /// interval.tick().await; /// - /// // approximately 250ms have elapsed. - /// } + /// // approximately 250ms have elapsed. + /// # } /// ``` pub fn reset(&mut self) { self.delay.as_mut().reset(Instant::now() + self.period); @@ -538,20 +538,20 @@ impl Interval { /// /// use std::time::Duration; /// - /// #[tokio::main] - /// async fn main() { - /// let mut interval = time::interval(Duration::from_millis(100)); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let mut interval = time::interval(Duration::from_millis(100)); /// - /// interval.tick().await; + /// interval.tick().await; /// - /// time::sleep(Duration::from_millis(50)).await; - /// interval.reset_immediately(); + /// time::sleep(Duration::from_millis(50)).await; + /// interval.reset_immediately(); /// - /// interval.tick().await; - /// interval.tick().await; + /// interval.tick().await; + /// interval.tick().await; /// - /// // approximately 150ms have elapsed. - /// } + /// // approximately 150ms have elapsed. + /// # } /// ``` pub fn reset_immediately(&mut self) { self.delay.as_mut().reset(Instant::now()); @@ -570,21 +570,21 @@ impl Interval { /// /// use std::time::Duration; /// - /// #[tokio::main] - /// async fn main() { - /// let mut interval = time::interval(Duration::from_millis(100)); - /// interval.tick().await; + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let mut interval = time::interval(Duration::from_millis(100)); + /// interval.tick().await; /// - /// time::sleep(Duration::from_millis(50)).await; + /// time::sleep(Duration::from_millis(50)).await; /// - /// let after = Duration::from_millis(20); - /// interval.reset_after(after); + /// let after = Duration::from_millis(20); + /// interval.reset_after(after); /// - /// interval.tick().await; - /// interval.tick().await; + /// interval.tick().await; + /// interval.tick().await; /// - /// // approximately 170ms have elapsed. - /// } + /// // approximately 170ms have elapsed. + /// # } /// ``` pub fn reset_after(&mut self, after: Duration) { self.delay.as_mut().reset(Instant::now() + after); @@ -606,21 +606,21 @@ impl Interval { /// /// use std::time::Duration; /// - /// #[tokio::main] - /// async fn main() { - /// let mut interval = time::interval(Duration::from_millis(100)); - /// interval.tick().await; + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let mut interval = time::interval(Duration::from_millis(100)); + /// interval.tick().await; /// - /// time::sleep(Duration::from_millis(50)).await; + /// time::sleep(Duration::from_millis(50)).await; /// - /// let deadline = Instant::now() + Duration::from_millis(30); - /// interval.reset_at(deadline); + /// let deadline = Instant::now() + Duration::from_millis(30); + /// interval.reset_at(deadline); /// - /// interval.tick().await; - /// interval.tick().await; + /// interval.tick().await; + /// interval.tick().await; /// - /// // approximately 180ms have elapsed. - /// } + /// // approximately 180ms have elapsed. + /// # } /// ``` pub fn reset_at(&mut self, deadline: Instant) { self.delay.as_mut().reset(deadline); diff --git a/tokio/src/time/mod.rs b/tokio/src/time/mod.rs index c0cd7c62..8627a783 100644 --- a/tokio/src/time/mod.rs +++ b/tokio/src/time/mod.rs @@ -27,11 +27,11 @@ //! use std::time::Duration; //! use tokio::time::sleep; //! -//! #[tokio::main] -//! async fn main() { -//! sleep(Duration::from_millis(100)).await; -//! println!("100 ms have elapsed"); -//! } +//! # #[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. @@ -71,14 +71,14 @@ //! time::sleep(time::Duration::from_secs(1)).await //! } //! -//! #[tokio::main] -//! 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; -//! } +//! # #[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() diff --git a/tokio/src/time/sleep.rs b/tokio/src/time/sleep.rs index 1e3fe80d..87261057 100644 --- a/tokio/src/time/sleep.rs +++ b/tokio/src/time/sleep.rs @@ -28,11 +28,11 @@ use std::task::{self, ready, Poll}; /// ``` /// use tokio::time::{sleep_until, Instant, Duration}; /// -/// #[tokio::main] -/// async fn main() { -/// sleep_until(Instant::now() + Duration::from_millis(100)).await; -/// println!("100 ms have elapsed"); -/// } +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// sleep_until(Instant::now() + Duration::from_millis(100)).await; +/// println!("100 ms have elapsed"); +/// # } /// ``` /// /// See the documentation for the [`Sleep`] type for more examples. @@ -88,11 +88,11 @@ pub fn sleep_until(deadline: Instant) -> Sleep { /// ``` /// use tokio::time::{sleep, Duration}; /// -/// #[tokio::main] -/// async fn main() { -/// sleep(Duration::from_millis(100)).await; -/// println!("100 ms have elapsed"); -/// } +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() { +/// sleep(Duration::from_millis(100)).await; +/// println!("100 ms have elapsed"); +/// # } /// ``` /// /// See the documentation for the [`Sleep`] type for more examples. @@ -143,11 +143,11 @@ pin_project! { /// ``` /// use tokio::time::{sleep, Duration}; /// - /// #[tokio::main] - /// async fn main() { - /// sleep(Duration::from_millis(100)).await; - /// println!("100 ms have elapsed"); - /// } + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// sleep(Duration::from_millis(100)).await; + /// println!("100 ms have elapsed"); + /// # } /// ``` /// /// Use with [`select!`]. Pinning the `Sleep` with [`tokio::pin!`] is @@ -155,20 +155,20 @@ pin_project! { /// ```no_run /// use tokio::time::{self, Duration, Instant}; /// - /// #[tokio::main] - /// async fn main() { - /// let sleep = time::sleep(Duration::from_millis(10)); - /// tokio::pin!(sleep); + /// # #[tokio::main(flavor = "current_thread")] + /// # async fn main() { + /// let sleep = time::sleep(Duration::from_millis(10)); + /// tokio::pin!(sleep); /// - /// loop { - /// tokio::select! { - /// () = &mut sleep => { - /// println!("timer elapsed"); - /// sleep.as_mut().reset(Instant::now() + Duration::from_millis(50)); - /// }, - /// } + /// loop { + /// tokio::select! { + /// () = &mut sleep => { + /// println!("timer elapsed"); + /// sleep.as_mut().reset(Instant::now() + Duration::from_millis(50)); + /// }, /// } /// } + /// # } /// ``` /// Use in a struct with boxing. By pinning the `Sleep` with a `Box`, the /// `HasSleep` struct implements `Unpin`, even though `Sleep` does not.