diff --git a/futures-macro/src/select.rs b/futures-macro/src/select.rs index b317a4d360..bce2fa82bb 100644 --- a/futures-macro/src/select.rs +++ b/futures-macro/src/select.rs @@ -279,7 +279,7 @@ fn select_inner(input: TokenStream, random: bool) -> TokenStream { let shuffle = if random { quote! { - __futures_crate::async_await::shuffle(&mut __select_arr); + __futures_crate::shuffle(&mut __select_arr); } } else { quote!() diff --git a/futures-macro/src/stream_select.rs b/futures-macro/src/stream_select.rs index 9927b53073..7571a565b2 100644 --- a/futures-macro/src/stream_select.rs +++ b/futures-macro/src/stream_select.rs @@ -56,7 +56,7 @@ pub(crate) fn stream_select(input: TokenStream) -> Result(_: &T) {} diff --git a/futures-util/src/async_await/random.rs b/futures-util/src/async_await/random.rs deleted file mode 100644 index a799ef0a1e..0000000000 --- a/futures-util/src/async_await/random.rs +++ /dev/null @@ -1,54 +0,0 @@ -use std::{ - cell::Cell, - collections::hash_map::DefaultHasher, - hash::Hasher, - num::Wrapping, - sync::atomic::{AtomicUsize, Ordering}, -}; - -// Based on [Fisher–Yates shuffle]. -// -// [Fisher–Yates shuffle]: https://en.wikipedia.org/wiki/Fisher–Yates_shuffle -#[doc(hidden)] -pub fn shuffle(slice: &mut [T]) { - for i in (1..slice.len()).rev() { - slice.swap(i, gen_index(i + 1)); - } -} - -/// Return a value from `0..n`. -pub(crate) fn gen_index(n: usize) -> usize { - (random() % n as u64) as usize -} - -/// Pseudorandom number generator based on [xorshift*]. -/// -/// [xorshift*]: https://en.wikipedia.org/wiki/Xorshift#xorshift* -fn random() -> u64 { - thread_local! { - static RNG: Cell> = Cell::new(Wrapping(prng_seed())); - } - - fn prng_seed() -> u64 { - static COUNTER: AtomicUsize = AtomicUsize::new(0); - - // Any non-zero seed will do - let mut seed = 0; - while seed == 0 { - let mut hasher = DefaultHasher::new(); - hasher.write_usize(COUNTER.fetch_add(1, Ordering::Relaxed)); - seed = hasher.finish(); - } - seed - } - - RNG.with(|rng| { - let mut x = rng.get(); - debug_assert_ne!(x.0, 0); - x ^= x >> 12; - x ^= x << 25; - x ^= x >> 27; - rng.set(x); - x.0.wrapping_mul(0x2545_f491_4f6c_dd1d) - }) -} diff --git a/futures-util/src/future/select.rs b/futures-util/src/future/select.rs index 3a5a05be4a..686c5c313b 100644 --- a/futures-util/src/future/select.rs +++ b/futures-util/src/future/select.rs @@ -113,12 +113,14 @@ where } #[cfg(feature = "std")] - if crate::gen_index(2) == 0 { - poll_wrap!(a, b, Either::Left); - poll_wrap!(b, a, Either::Right); - } else { - poll_wrap!(b, a, Either::Right); - poll_wrap!(a, b, Either::Left); + { + if crate::gen_index(2) == 0 { + poll_wrap!(a, b, Either::Left); + poll_wrap!(b, a, Either::Right); + } else { + poll_wrap!(b, a, Either::Right); + poll_wrap!(a, b, Either::Left); + } } #[cfg(not(feature = "std"))] diff --git a/futures-util/src/future/select_ok.rs b/futures-util/src/future/select_ok.rs index 00349614f2..3d6fa67cc1 100644 --- a/futures-util/src/future/select_ok.rs +++ b/futures-util/src/future/select_ok.rs @@ -59,7 +59,9 @@ impl Future for SelectOk { fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let Self { inner } = &mut *self; #[cfg(feature = "std")] - crate::shuffle(inner); + { + crate::shuffle(inner); + } // loop until we've either exhausted all errors, a success was hit, or nothing is ready loop { let item = inner.iter_mut().enumerate().find_map(|(i, f)| match f.try_poll_unpin(cx) { diff --git a/futures-util/src/future/try_select.rs b/futures-util/src/future/try_select.rs index f2811bf364..a24525bbdc 100644 --- a/futures-util/src/future/try_select.rs +++ b/futures-util/src/future/try_select.rs @@ -90,10 +90,12 @@ where } #[cfg(feature = "std")] - if crate::gen_index(2) == 0 { - poll_wrap!(a, b, Either::Left, Either::Right) - } else { - poll_wrap!(b, a, Either::Right, Either::Left) + { + if crate::gen_index(2) == 0 { + poll_wrap!(a, b, Either::Left, Either::Right) + } else { + poll_wrap!(b, a, Either::Right, Either::Left) + } } #[cfg(not(feature = "std"))] diff --git a/futures-util/src/lib.rs b/futures-util/src/lib.rs index e00faf4775..210e38fb12 100644 --- a/futures-util/src/lib.rs +++ b/futures-util/src/lib.rs @@ -37,6 +37,12 @@ mod async_await; #[doc(hidden)] pub use self::async_await::*; +#[cfg(feature = "std")] +mod random; +#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/64762 +#[cfg(feature = "std")] +pub use self::random::*; + // Not public API. #[cfg(feature = "async-await")] #[doc(hidden)]