Struct futures_util::stream::futures_unordered::FuturesUnordered
source · pub struct FuturesUnordered<Fut> {
ready_to_run_queue: Arc<ReadyToRunQueue<Fut>>,
head_all: AtomicPtr<Task<Fut>>,
is_terminated: AtomicBool,
}
Expand description
A set of futures which may complete in any order.
See FuturesOrdered
for a version of this
type that preserves a FIFO order.
This structure is optimized to manage a large number of futures.
Futures managed by FuturesUnordered
will only be polled when they
generate wake-up notifications. This reduces the required amount of work
needed to poll large numbers of futures.
FuturesUnordered
can be filled by collect
ing an
iterator of futures into a FuturesUnordered
, or by
push
ing futures onto an existing
FuturesUnordered
. When new futures are added,
poll_next
must be called in order to begin receiving
wake-ups for new futures.
Note that you can create a ready-made FuturesUnordered
via the
collect
method, or you can start with an empty set
with the FuturesUnordered::new
constructor.
This type is only available when the std
or alloc
feature of this
library is activated, and it is activated by default.
Fields§
§ready_to_run_queue: Arc<ReadyToRunQueue<Fut>>
§head_all: AtomicPtr<Task<Fut>>
§is_terminated: AtomicBool
Implementations§
source§impl<Fut> FuturesUnordered<Fut>
impl<Fut> FuturesUnordered<Fut>
sourcepub fn new() -> Self
pub fn new() -> Self
Constructs a new, empty FuturesUnordered
.
The returned FuturesUnordered
does not contain any futures.
In this state, FuturesUnordered::poll_next
will
return Poll::Ready(None)
.
sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Returns the number of futures contained in the set.
This represents the total number of in-flight futures.
sourcepub fn push(&self, future: Fut)
pub fn push(&self, future: Fut)
Push a future into the set.
This method adds the given future to the set. This method will not
call poll
on the submitted future. The caller must
ensure that FuturesUnordered::poll_next
is called
in order to receive wake-up notifications for the given future.
sourcepub fn iter(&self) -> Iter<'_, Fut> ⓘwhere
Fut: Unpin,
pub fn iter(&self) -> Iter<'_, Fut> ⓘwhere
Fut: Unpin,
Returns an iterator that allows inspecting each future in the set.
sourcepub fn iter_pin_ref(self: Pin<&Self>) -> IterPinRef<'_, Fut> ⓘ
pub fn iter_pin_ref(self: Pin<&Self>) -> IterPinRef<'_, Fut> ⓘ
Returns an iterator that allows inspecting each future in the set.
sourcepub fn iter_mut(&mut self) -> IterMut<'_, Fut> ⓘwhere
Fut: Unpin,
pub fn iter_mut(&mut self) -> IterMut<'_, Fut> ⓘwhere
Fut: Unpin,
Returns an iterator that allows modifying each future in the set.
sourcepub fn iter_pin_mut(self: Pin<&mut Self>) -> IterPinMut<'_, Fut> ⓘ
pub fn iter_pin_mut(self: Pin<&mut Self>) -> IterPinMut<'_, Fut> ⓘ
Returns an iterator that allows modifying each future in the set.
sourcefn atomic_load_head_and_len_all(&self) -> (*const Task<Fut>, usize)
fn atomic_load_head_and_len_all(&self) -> (*const Task<Fut>, usize)
Returns the current head node and number of futures in the list of all
futures within a context where access is shared with other threads
(mostly for use with the len
and iter_pin_ref
methods).
sourcefn release_task(&mut self, task: Arc<Task<Fut>>)
fn release_task(&mut self, task: Arc<Task<Fut>>)
Releases the task. It destroys the future inside and either drops
the Arc<Task>
or transfers ownership to the ready to run queue.
The task this method is called on must have been unlinked before.
sourcefn link(&self, task: Arc<Task<Fut>>) -> *const Task<Fut>
fn link(&self, task: Arc<Task<Fut>>) -> *const Task<Fut>
Insert a new task into the internal linked list.
sourceunsafe fn unlink(&mut self, task: *const Task<Fut>) -> Arc<Task<Fut>>
unsafe fn unlink(&mut self, task: *const Task<Fut>) -> Arc<Task<Fut>>
Remove the task from the linked list tracking all tasks currently
managed by FuturesUnordered
.
This method is unsafe because it has be guaranteed that task
is a
valid pointer.
sourcefn pending_next_all(&self) -> *mut Task<Fut>
fn pending_next_all(&self) -> *mut Task<Fut>
Returns the reserved value for Task::next_all
to indicate a pending
assignment from the thread that inserted the task.
FuturesUnordered::link
needs to update Task
pointers in an order
that ensures any iterators created on other threads can correctly
traverse the entire Task
list using the chain of next_all
pointers.
This could be solved with a compare-exchange loop that stores the
current head_all
in next_all
and swaps out head_all
with the new
Task
pointer if the head hasn’t already changed. Under heavy thread
contention, this compare-exchange loop could become costly.
An alternative is to initialize next_all
to a reserved pending state
first, perform an atomic swap on head_all
, and finally update
next_all
with the old head node. Iterators will then either see the
pending state value or the correct next node pointer, and can reload
next_all
as needed until the correct value is loaded. The number of
retries needed (if any) would be small and will always be finite, so
this should generally perform better than the compare-exchange loop.
A valid Task
pointer in the head_all
list is guaranteed to never be
this value, so it is safe to use as a reserved value until the correct
value can be written.
source§impl<Fut> FuturesUnordered<Fut>
impl<Fut> FuturesUnordered<Fut>
Trait Implementations§
source§impl<Fut> Debug for FuturesUnordered<Fut>
impl<Fut> Debug for FuturesUnordered<Fut>
source§impl<Fut> Default for FuturesUnordered<Fut>
impl<Fut> Default for FuturesUnordered<Fut>
source§impl<Fut> Drop for FuturesUnordered<Fut>
impl<Fut> Drop for FuturesUnordered<Fut>
source§impl<Fut> Extend<Fut> for FuturesUnordered<Fut>
impl<Fut> Extend<Fut> for FuturesUnordered<Fut>
source§fn extend<I>(&mut self, iter: I)where
I: IntoIterator<Item = Fut>,
fn extend<I>(&mut self, iter: I)where
I: IntoIterator<Item = Fut>,
source§fn extend_one(&mut self, item: A)
fn extend_one(&mut self, item: A)
extend_one
)source§fn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one
)source§impl<Fut> FromIterator<Fut> for FuturesUnordered<Fut>
impl<Fut> FromIterator<Fut> for FuturesUnordered<Fut>
source§fn from_iter<I>(iter: I) -> Selfwhere
I: IntoIterator<Item = Fut>,
fn from_iter<I>(iter: I) -> Selfwhere
I: IntoIterator<Item = Fut>,
source§impl<Fut: Future> FusedStream for FuturesUnordered<Fut>
impl<Fut: Future> FusedStream for FuturesUnordered<Fut>
source§fn is_terminated(&self) -> bool
fn is_terminated(&self) -> bool
true
if the stream should no longer be polled.source§impl<'a, Fut: Unpin> IntoIterator for &'a FuturesUnordered<Fut>
impl<'a, Fut: Unpin> IntoIterator for &'a FuturesUnordered<Fut>
source§impl<'a, Fut: Unpin> IntoIterator for &'a mut FuturesUnordered<Fut>
impl<'a, Fut: Unpin> IntoIterator for &'a mut FuturesUnordered<Fut>
source§impl<Fut: Unpin> IntoIterator for FuturesUnordered<Fut>
impl<Fut: Unpin> IntoIterator for FuturesUnordered<Fut>
source§impl LocalSpawn for FuturesUnordered<LocalFutureObj<'_, ()>>
impl LocalSpawn for FuturesUnordered<LocalFutureObj<'_, ()>>
source§fn spawn_local_obj(
&self,
future_obj: LocalFutureObj<'static, ()>,
) -> Result<(), SpawnError>
fn spawn_local_obj( &self, future_obj: LocalFutureObj<'static, ()>, ) -> Result<(), SpawnError>
source§fn status_local(&self) -> Result<(), SpawnError>
fn status_local(&self) -> Result<(), SpawnError>
source§impl<Fut: Future> Stream for FuturesUnordered<Fut>
impl<Fut: Future> Stream for FuturesUnordered<Fut>
impl<Fut: Send> Send for FuturesUnordered<Fut>
impl<Fut: Send + Sync> Sync for FuturesUnordered<Fut>
impl<Fut> Unpin for FuturesUnordered<Fut>
Auto Trait Implementations§
impl<Fut> !Freeze for FuturesUnordered<Fut>
impl<Fut> !RefUnwindSafe for FuturesUnordered<Fut>
impl<Fut> !UnwindSafe for FuturesUnordered<Fut>
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<Sp> LocalSpawnExt for Spwhere
Sp: LocalSpawn + ?Sized,
impl<Sp> LocalSpawnExt for Spwhere
Sp: LocalSpawn + ?Sized,
source§fn spawn_local<Fut>(&self, future: Fut) -> Result<(), SpawnError>
fn spawn_local<Fut>(&self, future: Fut) -> Result<(), SpawnError>
()
to
completion. Read moresource§fn spawn_local_with_handle<Fut>(
&self,
future: Fut,
) -> Result<RemoteHandle<Fut::Output>, SpawnError>where
Fut: Future + 'static,
fn spawn_local_with_handle<Fut>(
&self,
future: Fut,
) -> Result<RemoteHandle<Fut::Output>, SpawnError>where
Fut: Future + 'static,
source§impl<Sp> SpawnExt for Sp
impl<Sp> SpawnExt for Sp
source§fn spawn<Fut>(&self, future: Fut) -> Result<(), SpawnError>
fn spawn<Fut>(&self, future: Fut) -> Result<(), SpawnError>
()
to
completion. Read moresource§fn spawn_with_handle<Fut>(
&self,
future: Fut,
) -> Result<RemoteHandle<Fut::Output>, SpawnError>
fn spawn_with_handle<Fut>( &self, future: Fut, ) -> Result<RemoteHandle<Fut::Output>, SpawnError>
source§impl<T> StreamExt for T
impl<T> StreamExt for T
source§fn next(&mut self) -> Next<'_, Self> ⓘwhere
Self: Unpin,
fn next(&mut self) -> Next<'_, Self> ⓘwhere
Self: Unpin,
source§fn into_future(self) -> StreamFuture<Self> ⓘ
fn into_future(self) -> StreamFuture<Self> ⓘ
source§fn map<T, F>(self, f: F) -> Map<Self, F>
fn map<T, F>(self, f: F) -> Map<Self, F>
source§fn enumerate(self) -> Enumerate<Self>where
Self: Sized,
fn enumerate(self) -> Enumerate<Self>where
Self: Sized,
source§fn filter<Fut, F>(self, f: F) -> Filter<Self, Fut, F>
fn filter<Fut, F>(self, f: F) -> Filter<Self, Fut, F>
source§fn filter_map<Fut, T, F>(self, f: F) -> FilterMap<Self, Fut, F>
fn filter_map<Fut, T, F>(self, f: F) -> FilterMap<Self, Fut, F>
source§fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
source§fn collect<C: Default + Extend<Self::Item>>(self) -> Collect<Self, C> ⓘwhere
Self: Sized,
fn collect<C: Default + Extend<Self::Item>>(self) -> Collect<Self, C> ⓘwhere
Self: Sized,
source§fn unzip<A, B, FromA, FromB>(self) -> Unzip<Self, FromA, FromB> ⓘ
fn unzip<A, B, FromA, FromB>(self) -> Unzip<Self, FromA, FromB> ⓘ
source§fn concat(self) -> Concat<Self> ⓘwhere
Self: Sized,
Self::Item: Extend<<<Self as Stream>::Item as IntoIterator>::Item> + IntoIterator + Default,
fn concat(self) -> Concat<Self> ⓘwhere
Self: Sized,
Self::Item: Extend<<<Self as Stream>::Item as IntoIterator>::Item> + IntoIterator + Default,
source§fn count(self) -> Count<Self> ⓘwhere
Self: Sized,
fn count(self) -> Count<Self> ⓘwhere
Self: Sized,
source§fn fold<T, Fut, F>(self, init: T, f: F) -> Fold<Self, Fut, T, F> ⓘ
fn fold<T, Fut, F>(self, init: T, f: F) -> Fold<Self, Fut, T, F> ⓘ
source§fn any<Fut, F>(self, f: F) -> Any<Self, Fut, F> ⓘ
fn any<Fut, F>(self, f: F) -> Any<Self, Fut, F> ⓘ
true
if any element in stream satisfied a predicate. Read moresource§fn all<Fut, F>(self, f: F) -> All<Self, Fut, F> ⓘ
fn all<Fut, F>(self, f: F) -> All<Self, Fut, F> ⓘ
true
if all element in stream satisfied a predicate. Read moresource§fn flatten(self) -> Flatten<Self>
fn flatten(self) -> Flatten<Self>
source§fn flatten_unordered(
self,
limit: impl Into<Option<usize>>,
) -> FlattenUnordered<Self>
fn flatten_unordered( self, limit: impl Into<Option<usize>>, ) -> FlattenUnordered<Self>
source§fn flat_map_unordered<U, F>(
self,
limit: impl Into<Option<usize>>,
f: F,
) -> FlatMapUnordered<Self, U, F>
fn flat_map_unordered<U, F>( self, limit: impl Into<Option<usize>>, f: F, ) -> FlatMapUnordered<Self, U, F>
StreamExt::map
but flattens nested Stream
s
and polls them concurrently, yielding items in any order, as they made
available. Read moresource§fn scan<S, B, Fut, F>(self, initial_state: S, f: F) -> Scan<Self, S, Fut, F>
fn scan<S, B, Fut, F>(self, initial_state: S, f: F) -> Scan<Self, S, Fut, F>
StreamExt::fold
that holds internal state
and produces a new stream. Read moresource§fn skip_while<Fut, F>(self, f: F) -> SkipWhile<Self, Fut, F>
fn skip_while<Fut, F>(self, f: F) -> SkipWhile<Self, Fut, F>
true
. Read moresource§fn take_while<Fut, F>(self, f: F) -> TakeWhile<Self, Fut, F>
fn take_while<Fut, F>(self, f: F) -> TakeWhile<Self, Fut, F>
true
. Read moresource§fn take_until<Fut>(self, fut: Fut) -> TakeUntil<Self, Fut>
fn take_until<Fut>(self, fut: Fut) -> TakeUntil<Self, Fut>
source§fn for_each<Fut, F>(self, f: F) -> ForEach<Self, Fut, F> ⓘ
fn for_each<Fut, F>(self, f: F) -> ForEach<Self, Fut, F> ⓘ
source§fn for_each_concurrent<Fut, F>(
self,
limit: impl Into<Option<usize>>,
f: F,
) -> ForEachConcurrent<Self, Fut, F> ⓘ
fn for_each_concurrent<Fut, F>( self, limit: impl Into<Option<usize>>, f: F, ) -> ForEachConcurrent<Self, Fut, F> ⓘ
source§fn take(self, n: usize) -> Take<Self>where
Self: Sized,
fn take(self, n: usize) -> Take<Self>where
Self: Sized,
n
items of the underlying stream. Read moresource§fn skip(self, n: usize) -> Skip<Self>where
Self: Sized,
fn skip(self, n: usize) -> Skip<Self>where
Self: Sized,
n
items of the underlying stream. Read moresource§fn catch_unwind(self) -> CatchUnwind<Self>where
Self: Sized + UnwindSafe,
fn catch_unwind(self) -> CatchUnwind<Self>where
Self: Sized + UnwindSafe,
source§fn boxed<'a>(self) -> BoxStream<'a, Self::Item>
fn boxed<'a>(self) -> BoxStream<'a, Self::Item>
source§fn boxed_local<'a>(self) -> LocalBoxStream<'a, Self::Item>where
Self: Sized + 'a,
fn boxed_local<'a>(self) -> LocalBoxStream<'a, Self::Item>where
Self: Sized + 'a,
source§fn buffered(self, n: usize) -> Buffered<Self>
fn buffered(self, n: usize) -> Buffered<Self>
source§fn buffer_unordered(self, n: usize) -> BufferUnordered<Self>
fn buffer_unordered(self, n: usize) -> BufferUnordered<Self>
source§fn zip<St>(self, other: St) -> Zip<Self, St>
fn zip<St>(self, other: St) -> Zip<Self, St>
source§fn peekable(self) -> Peekable<Self>where
Self: Sized,
fn peekable(self) -> Peekable<Self>where
Self: Sized,
peek
method. Read moresource§fn chunks(self, capacity: usize) -> Chunks<Self>where
Self: Sized,
fn chunks(self, capacity: usize) -> Chunks<Self>where
Self: Sized,
source§fn ready_chunks(self, capacity: usize) -> ReadyChunks<Self>where
Self: Sized,
fn ready_chunks(self, capacity: usize) -> ReadyChunks<Self>where
Self: Sized,
source§fn forward<S>(self, sink: S) -> Forward<Self, S> ⓘ
fn forward<S>(self, sink: S) -> Forward<Self, S> ⓘ
source§fn split<Item>(self) -> (SplitSink<Self, Item>, SplitStream<Self>)
fn split<Item>(self) -> (SplitSink<Self, Item>, SplitStream<Self>)
source§fn inspect<F>(self, f: F) -> Inspect<Self, F>
fn inspect<F>(self, f: F) -> Inspect<Self, F>
source§fn left_stream<B>(self) -> Either<Self, B> ⓘ
fn left_stream<B>(self) -> Either<Self, B> ⓘ
source§fn right_stream<B>(self) -> Either<B, Self> ⓘ
fn right_stream<B>(self) -> Either<B, Self> ⓘ
source§fn poll_next_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>where
Self: Unpin,
fn poll_next_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>where
Self: Unpin,
Stream::poll_next
on Unpin
stream types.source§fn select_next_some(&mut self) -> SelectNextSome<'_, Self> ⓘwhere
Self: Unpin + FusedStream,
fn select_next_some(&mut self) -> SelectNextSome<'_, Self> ⓘwhere
Self: Unpin + FusedStream,
source§impl<S> TryStreamExt for S
impl<S> TryStreamExt for S
source§fn err_into<E>(self) -> ErrInto<Self, E>
fn err_into<E>(self) -> ErrInto<Self, E>
source§fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
source§fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
source§fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
f
. Read moresource§fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
f
. Read moresource§fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
source§fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
source§fn into_stream(self) -> IntoStream<Self>where
Self: Sized,
fn into_stream(self) -> IntoStream<Self>where
Self: Sized,
source§fn try_next(&mut self) -> TryNext<'_, Self> ⓘwhere
Self: Unpin,
fn try_next(&mut self) -> TryNext<'_, Self> ⓘwhere
Self: Unpin,
source§fn try_for_each<Fut, F>(self, f: F) -> TryForEach<Self, Fut, F> ⓘ
fn try_for_each<Fut, F>(self, f: F) -> TryForEach<Self, Fut, F> ⓘ
source§fn try_skip_while<Fut, F>(self, f: F) -> TrySkipWhile<Self, Fut, F>
fn try_skip_while<Fut, F>(self, f: F) -> TrySkipWhile<Self, Fut, F>
true
. Read moresource§fn try_take_while<Fut, F>(self, f: F) -> TryTakeWhile<Self, Fut, F>
fn try_take_while<Fut, F>(self, f: F) -> TryTakeWhile<Self, Fut, F>
true
. Read moresource§fn try_for_each_concurrent<Fut, F>(
self,
limit: impl Into<Option<usize>>,
f: F,
) -> TryForEachConcurrent<Self, Fut, F> ⓘ
fn try_for_each_concurrent<Fut, F>( self, limit: impl Into<Option<usize>>, f: F, ) -> TryForEachConcurrent<Self, Fut, F> ⓘ
source§fn try_collect<C: Default + Extend<Self::Ok>>(self) -> TryCollect<Self, C> ⓘwhere
Self: Sized,
fn try_collect<C: Default + Extend<Self::Ok>>(self) -> TryCollect<Self, C> ⓘwhere
Self: Sized,
source§fn try_chunks(self, capacity: usize) -> TryChunks<Self>where
Self: Sized,
fn try_chunks(self, capacity: usize) -> TryChunks<Self>where
Self: Sized,
source§fn try_ready_chunks(self, capacity: usize) -> TryReadyChunks<Self>where
Self: Sized,
fn try_ready_chunks(self, capacity: usize) -> TryReadyChunks<Self>where
Self: Sized,
source§fn try_filter<Fut, F>(self, f: F) -> TryFilter<Self, Fut, F>
fn try_filter<Fut, F>(self, f: F) -> TryFilter<Self, Fut, F>
source§fn try_filter_map<Fut, F, T>(self, f: F) -> TryFilterMap<Self, Fut, F>
fn try_filter_map<Fut, F, T>(self, f: F) -> TryFilterMap<Self, Fut, F>
source§fn try_flatten_unordered(
self,
limit: impl Into<Option<usize>>,
) -> TryFlattenUnordered<Self>
fn try_flatten_unordered( self, limit: impl Into<Option<usize>>, ) -> TryFlattenUnordered<Self>
source§fn try_flatten(self) -> TryFlatten<Self>
fn try_flatten(self) -> TryFlatten<Self>
source§fn try_fold<T, Fut, F>(self, init: T, f: F) -> TryFold<Self, Fut, T, F> ⓘ
fn try_fold<T, Fut, F>(self, init: T, f: F) -> TryFold<Self, Fut, T, F> ⓘ
source§fn try_concat(self) -> TryConcat<Self> ⓘwhere
Self: Sized,
Self::Ok: Extend<<<Self as TryStream>::Ok as IntoIterator>::Item> + IntoIterator + Default,
fn try_concat(self) -> TryConcat<Self> ⓘwhere
Self: Sized,
Self::Ok: Extend<<<Self as TryStream>::Ok as IntoIterator>::Item> + IntoIterator + Default,
source§fn try_buffer_unordered(self, n: usize) -> TryBufferUnordered<Self>
fn try_buffer_unordered(self, n: usize) -> TryBufferUnordered<Self>
source§fn try_buffered(self, n: usize) -> TryBuffered<Self>
fn try_buffered(self, n: usize) -> TryBuffered<Self>
source§fn try_poll_next_unpin(
&mut self,
cx: &mut Context<'_>,
) -> Poll<Option<Result<Self::Ok, Self::Error>>>where
Self: Unpin,
fn try_poll_next_unpin(
&mut self,
cx: &mut Context<'_>,
) -> Poll<Option<Result<Self::Ok, Self::Error>>>where
Self: Unpin,
TryStream::try_poll_next
on Unpin
stream types.source§fn into_async_read(self) -> IntoAsyncRead<Self>
fn into_async_read(self) -> IntoAsyncRead<Self>
AsyncBufRead
. Read moresource§fn try_all<Fut, F>(self, f: F) -> TryAll<Self, Fut, F> ⓘ
fn try_all<Fut, F>(self, f: F) -> TryAll<Self, Fut, F> ⓘ
Err
is encountered or if an Ok
item is found
that does not satisfy the predicate. Read more