···11use futures_core::{ScopedFuture, Wake};
22use futures_util::{MaybeDone, MaybeDoneState, maybe_done};
33-use std::cell::{Cell, UnsafeCell};
44-use std::sync::atomic::Ordering;
55-use std::{sync::atomic::AtomicBool, task::Poll};
33+use std::{cell::Cell, task::Poll};
6477-/// from yoshuawuyts/futures-concurrency
55+/// from [futures-concurrency](https://github.com/yoshuawuyts/futures-concurrency/tree/main)
86/// Wait for all futures to complete.
97///
108/// Awaits multiple futures simultaneously, returning the output of the futures
···1210pub trait Join<'scope> {
1311 /// The resulting output type.
1412 type Output;
1313+1514 /// The [`ScopedFuture`] implementation returned by this method.
1615 type Future: ScopedFuture<'scope, Output = Self::Output>;
1616+1717 /// Waits for multiple futures to complete.
1818 ///
1919 /// Awaits multiple futures simultaneously, returning the output of the futures
2020 /// in the same container type they we're created once all complete.
2121 ///
2222- /// # Examples
2323- ///
2424- /// Awaiting multiple futures of the same type can be done using either a vector
2525- /// or an array.
2626- /// ```rust
2727- /// # futures::executor::block_on(async {
2828- /// use futures_concurrency::prelude::*;
2929- ///
3030- /// // all futures passed here are of the same type
3131- /// let fut1 = core::future::ready(1);
3232- /// let fut2 = core::future::ready(2);
3333- /// let fut3 = core::future::ready(3);
3434- ///
3535- /// let outputs = [fut1, fut2, fut3].join().await;
3636- /// assert_eq!(outputs, [1, 2, 3]);
3737- /// # })
3838- /// ```
3939- ///
4040- /// In practice however, it's common to want to await multiple futures of
4141- /// different types. For example if you have two different `async {}` blocks,
4242- /// you want to `.await`. To do that, you can call `.join` on tuples of futures.
4343- /// ```rust
4444- /// # futures::executor::block_on(async {
4545- /// use futures_concurrency::prelude::*;
4646- ///
4747- /// async fn some_async_fn() -> usize { 3 }
4848- ///
4949- /// // the futures passed here are of different types
5050- /// let fut1 = core::future::ready(1);
5151- /// let fut2 = async { 2 };
5252- /// let fut3 = some_async_fn();
5353- /// // ^ NOTE: no `.await` here!
5454- ///
5555- /// let outputs = (fut1, fut2, fut3).join().await;
5656- /// assert_eq!(outputs, (1, 2, 3));
5757- /// # })
5858- /// ```
5959- ///
6060- /// <br><br>
6122 /// This function returns a new future which polls all futures concurrently.
6223 fn join(self) -> Self::Future;
6324}
64256526struct WakeStore<'scope> {
6627 parent: Cell<Option<&'scope dyn Wake<'scope>>>,
6767- ready: AtomicBool,
2828+ ready: Cell<bool>,
6829}
69307031impl<'scope> WakeStore<'scope> {
···7536 }
7637 }
7738 fn take_ready(&self) -> bool {
7878- self.ready.swap(false, Ordering::SeqCst)
3939+ self.ready.replace(false)
7940 }
8041}
81428243impl<'scope> Wake<'scope> for WakeStore<'scope> {
8344 fn wake(&self) {
8484- self.ready.swap(true, Ordering::SeqCst);
4545+ self.ready.replace(true);
8546 if let Some(parent) = &self.parent.get() {
8647 parent.wake();
8748 }
···10768 }
1086910970 #[allow(non_snake_case)]
7171+ #[must_use = "futures do nothing unless you `.await` or poll them"]
11072 pub struct $StructName<'scope, $($F: ScopedFuture<'scope>),+> {
11173 $($F: MaybeDone<'scope, $F>,)*
11274 wakers: $namespace::Wakers<'scope>,
···190152impl_join_tuple!(join10 Join10 A B C D E F G H I J);
191153impl_join_tuple!(join11 Join11 A B C D E F G H I J K);
192154impl_join_tuple!(join12 Join12 A B C D E F G H I J K L);
155155+156156+#[cfg(test)]
157157+mod tests {
158158+ use futures_util::poll_fn;
159159+160160+ use super::*;
161161+162162+ #[test]
163163+ fn basic() {
164164+ let f1 = poll_fn(|_| Poll::Ready(1));
165165+ let f2 = poll_fn(|_| Poll::Ready(2));
166166+ let dummy_waker = WakeStore::new();
167167+ assert_eq!((f1, f2).join().poll(&dummy_waker), Poll::Ready((1, 2)));
168168+ }
169169+}
+2
futures-util/src/lib.rs
···11mod maybe_done;
22+mod poll_fn;
2334use futures_core::ScopedFuture;
45pub use maybe_done::*;
66+pub use poll_fn::poll_fn;
5768// Just a helper function to ensure the futures we're returning all have the
79// right implementations.
+1
futures-util/src/maybe_done.rs
···88 task::{Poll, ready},
99};
10101111+#[must_use = "futures do nothing unless you `.await` or poll them"]
1112pub struct MaybeDone<'scope, Fut: ScopedFuture<'scope>> {
1213 state: UnsafeCell<MaybeDoneState<'scope, Fut>>,
1314}
+55
futures-util/src/poll_fn.rs
···11+use core::fmt;
22+use std::task::Poll;
33+44+use futures_core::{ScopedFuture, Wake};
55+66+use crate::assert_future;
77+88+/// Future for the [`poll_fn`] function.
99+#[must_use = "futures do nothing unless you `.await` or poll them"]
1010+pub struct PollFn<F> {
1111+ f: F,
1212+}
1313+1414+/// Creates a new future wrapping around a function returning [`Poll`].
1515+///
1616+/// Polling the returned future delegates to the wrapped function.
1717+///
1818+/// # Examples
1919+///
2020+/// ```
2121+/// # futures::executor::block_on(async {
2222+/// use futures::future::poll_fn;
2323+/// use futures::task::{Context, Poll};
2424+///
2525+/// fn read_line(_cx: &mut Context<'_>) -> Poll<String> {
2626+/// Poll::Ready("Hello, World!".into())
2727+/// }
2828+///
2929+/// let read_future = poll_fn(read_line);
3030+/// assert_eq!(read_future.await, "Hello, World!".to_owned());
3131+/// # });
3232+/// ```
3333+pub fn poll_fn<'scope, T, F>(f: F) -> PollFn<F>
3434+where
3535+ F: Fn(&'scope dyn Wake) -> Poll<T>,
3636+{
3737+ assert_future::<T, _>(PollFn { f })
3838+}
3939+4040+impl<F> fmt::Debug for PollFn<F> {
4141+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4242+ f.debug_struct("PollFn").finish()
4343+ }
4444+}
4545+4646+impl<'scope, T, F> ScopedFuture<'scope> for PollFn<F>
4747+where
4848+ F: Fn(&'scope dyn Wake) -> Poll<T>,
4949+{
5050+ type Output = T;
5151+5252+ fn poll(&self, wake: &'scope dyn Wake) -> Poll<T> {
5353+ (&self.f)(wake)
5454+ }
5555+}