1
+ use std:: cell:: Cell ;
1
2
use std:: iter;
3
+ use std:: pin:: Pin ;
4
+ use std:: rc:: Rc ;
2
5
use std:: sync:: Arc ;
6
+ use std:: task:: Context ;
3
7
4
8
use futures:: channel:: mpsc;
5
9
use futures:: executor:: block_on;
@@ -9,6 +13,7 @@ use futures::sink::SinkExt;
9
13
use futures:: stream:: { self , StreamExt } ;
10
14
use futures:: task:: Poll ;
11
15
use futures:: { ready, FutureExt } ;
16
+ use futures_core:: Stream ;
12
17
use futures_test:: task:: noop_context;
13
18
14
19
#[ test]
@@ -419,3 +424,40 @@ fn ready_chunks() {
419
424
assert_eq ! ( s. next( ) . await . unwrap( ) , vec![ 4 ] ) ;
420
425
} ) ;
421
426
}
427
+
428
+ struct SlowStream {
429
+ times_should_poll : usize ,
430
+ times_polled : Rc < Cell < usize > > ,
431
+ }
432
+ impl Stream for SlowStream {
433
+ type Item = usize ;
434
+
435
+ fn poll_next ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Option < Self :: Item > > {
436
+ self . times_polled . set ( self . times_polled . get ( ) + 1 ) ;
437
+ if self . times_polled . get ( ) % 2 == 0 {
438
+ cx. waker ( ) . wake_by_ref ( ) ;
439
+ return Poll :: Pending ;
440
+ }
441
+ if self . times_polled . get ( ) >= self . times_should_poll {
442
+ return Poll :: Ready ( None ) ;
443
+ }
444
+ Poll :: Ready ( Some ( self . times_polled . get ( ) ) )
445
+ }
446
+ }
447
+
448
+ #[ test]
449
+ fn select_with_strategy_doesnt_terminate_early ( ) {
450
+ for side in [ stream:: PollNext :: Left , stream:: PollNext :: Right ] {
451
+ let times_should_poll = 10 ;
452
+ let count = Rc :: new ( Cell :: new ( 0 ) ) ;
453
+ let b = stream:: iter ( [ 10 , 20 ] ) ;
454
+
455
+ let mut selected = stream:: select_with_strategy (
456
+ SlowStream { times_should_poll, times_polled : count. clone ( ) } ,
457
+ b,
458
+ |_: & mut ( ) | side,
459
+ ) ;
460
+ block_on ( async move { while selected. next ( ) . await . is_some ( ) { } } ) ;
461
+ assert_eq ! ( count. get( ) , times_should_poll + 1 ) ;
462
+ }
463
+ }
0 commit comments