@@ -325,46 +325,77 @@ fn flatten_unordered() {
325
325
} ) ;
326
326
}
327
327
328
+ fn timeout < I : Clone > ( time : Duration , value : I ) -> impl Future < Output = I > {
329
+ let ready = Arc :: new ( AtomicBool :: new ( false ) ) ;
330
+ let mut spawned = false ;
331
+
332
+ future:: poll_fn ( move |cx| {
333
+ if !spawned {
334
+ let waker = cx. waker ( ) . clone ( ) ;
335
+ let ready = ready. clone ( ) ;
336
+
337
+ std:: thread:: spawn ( move || {
338
+ std:: thread:: sleep ( time) ;
339
+ ready. store ( true , Ordering :: Release ) ;
340
+
341
+ waker. wake_by_ref ( )
342
+ } ) ;
343
+ spawned = true ;
344
+ }
345
+
346
+ if ready. load ( Ordering :: Acquire ) {
347
+ Poll :: Ready ( value. clone ( ) )
348
+ } else {
349
+ Poll :: Pending
350
+ }
351
+ } )
352
+ }
353
+
354
+ fn build_nested_fu < S : Stream + Unpin > ( st : S ) -> impl Stream < Item = S :: Item > + Unpin
355
+ where
356
+ S :: Item : Clone ,
357
+ {
358
+ let inner = st
359
+ . then ( |item| timeout ( Duration :: from_millis ( 50 ) , item) )
360
+ . enumerate ( )
361
+ . map ( |( idx, value) | {
362
+ stream:: once ( if idx % 2 == 0 {
363
+ future:: ready ( value) . left_future ( )
364
+ } else {
365
+ timeout ( Duration :: from_millis ( 100 ) , value) . right_future ( )
366
+ } )
367
+ } )
368
+ . flatten_unordered ( None ) ;
369
+
370
+ stream:: once ( future:: ready ( inner) ) . flatten_unordered ( None )
371
+ }
372
+
328
373
// nested `flatten_unordered`
329
374
let te = ThreadPool :: new ( ) . unwrap ( ) ;
330
- let handle = te
375
+ let base_handle = te
331
376
. spawn_with_handle ( async move {
332
- let inner = stream:: iter ( 0 ..10 )
333
- . then ( |_| {
334
- let task = Arc :: new ( AtomicBool :: new ( false ) ) ;
335
- let mut spawned = false ;
336
-
337
- future:: poll_fn ( move |cx| {
338
- if !spawned {
339
- let waker = cx. waker ( ) . clone ( ) ;
340
- let task = task. clone ( ) ;
341
-
342
- std:: thread:: spawn ( move || {
343
- std:: thread:: sleep ( Duration :: from_millis ( 500 ) ) ;
344
- task. store ( true , Ordering :: Release ) ;
345
-
346
- waker. wake_by_ref ( )
347
- } ) ;
348
- spawned = true ;
349
- }
350
-
351
- if task. load ( Ordering :: Acquire ) {
352
- Poll :: Ready ( Some ( ( ) ) )
353
- } else {
354
- Poll :: Pending
355
- }
356
- } )
357
- } )
358
- . map ( |_| stream:: once ( future:: ready ( ( ) ) ) )
359
- . flatten_unordered ( None ) ;
377
+ let fu = build_nested_fu ( stream:: iter ( 1 ..=10 ) ) ;
360
378
361
- let stream = stream:: once ( future:: ready ( inner) ) . flatten_unordered ( None ) ;
379
+ assert_eq ! ( fu. count( ) . await , 10 ) ;
380
+ } )
381
+ . unwrap ( ) ;
382
+
383
+ block_on ( base_handle) ;
384
+
385
+ let empty_state_move_handle = te
386
+ . spawn_with_handle ( async move {
387
+ let mut fu = build_nested_fu ( stream:: iter ( 1 ..10 ) ) ;
388
+ {
389
+ let mut cx = noop_context ( ) ;
390
+ let _ = fu. poll_next_unpin ( & mut cx) ;
391
+ let _ = fu. poll_next_unpin ( & mut cx) ;
392
+ }
362
393
363
- assert_eq ! ( stream . count( ) . await , 10 ) ;
394
+ assert_eq ! ( fu . count( ) . await , 9 ) ;
364
395
} )
365
396
. unwrap ( ) ;
366
397
367
- block_on ( handle ) ;
398
+ block_on ( empty_state_move_handle ) ;
368
399
}
369
400
370
401
#[ test]
0 commit comments