File tree 2 files changed +8
-4
lines changed
futures-util/src/stream/futures_unordered
2 files changed +8
-4
lines changed Original file line number Diff line number Diff line change 6
6
use crate :: task:: AtomicWaker ;
7
7
use alloc:: sync:: { Arc , Weak } ;
8
8
use core:: cell:: UnsafeCell ;
9
+ use core:: cmp;
9
10
use core:: fmt:: { self , Debug } ;
10
11
use core:: iter:: FromIterator ;
11
12
use core:: marker:: PhantomData ;
@@ -393,11 +394,14 @@ impl<Fut: Future> Stream for FuturesUnordered<Fut> {
393
394
// caps the number of calls to `poll` on underlying futures a single call to
394
395
// `poll_next` is allowed to make.
395
396
//
396
- // The value is the length of FuturesUnordered. This ensures that each
397
- // future is polled only once at most per iteration.
397
+ // The value itself is chosen somewhat arbitrarily. It needs to be high enough
398
+ // that amortize wakeup and scheduling costs, but low enough that we do not
399
+ // starve other tasks for long.
400
+ //
401
+ // Each future is polled only once *at most* per iteration.
398
402
//
399
403
// See also https://github.com/rust-lang/futures-rs/issues/2047.
400
- let yield_every = self . len ( ) ;
404
+ let yield_every = cmp :: min ( self . len ( ) , 32 ) ;
401
405
402
406
// Keep track of how many child futures we have polled,
403
407
// in case we want to forcibly yield.
Original file line number Diff line number Diff line change @@ -340,7 +340,7 @@ fn polled_only_once_at_most_per_iteration() {
340
340
341
341
let mut tasks = FuturesUnordered :: from_iter ( vec ! [ F :: default ( ) ; 33 ] ) ;
342
342
assert ! ( tasks. poll_next_unpin( cx) . is_pending( ) ) ;
343
- assert_eq ! ( 33 , tasks. iter( ) . filter( |f| f. polled) . count( ) ) ;
343
+ assert_eq ! ( 32 , tasks. iter( ) . filter( |f| f. polled) . count( ) ) ;
344
344
345
345
let mut tasks = FuturesUnordered :: < F > :: new ( ) ;
346
346
assert_eq ! ( Poll :: Ready ( None ) , tasks. poll_next_unpin( cx) ) ;
You can’t perform that action at this time.
0 commit comments