@@ -149,15 +149,26 @@ where
149
149
loop {
150
150
this. tasks . as_mut ( ) . poll_tasks_until_pending ( cx) ;
151
151
152
+ // If we can't get anymore tasks, and we don't have anything else to process, we report
153
+ // ready. Otherwise, if we have something to process, we report pending.
154
+ if this. tasks . is_empty ( ) && this. rx . is_terminated ( ) {
155
+ return Poll :: Ready ( ( ) ) ;
156
+ } else if this. rx . is_terminated ( ) {
157
+ return Poll :: Pending ;
158
+ }
159
+
160
+ // If we could accept tasks, but we don't have space we report pending.
152
161
if this. tasks . len ( ) >= * this. max_concurrency {
153
162
return Poll :: Pending ;
154
163
}
155
164
165
+ // At this point, we are free to start driving another future.
156
166
match this. rx . as_mut ( ) . poll_next ( cx) {
157
167
Poll :: Ready ( Some ( task) ) => this. tasks . push ( task) ,
158
168
// The stream is exhausted and there are no remaining tasks.
159
169
Poll :: Ready ( None ) if this. tasks . is_empty ( ) => return Poll :: Ready ( ( ) ) ,
160
- // The stream is exhausted but tasks remain active.
170
+ // The stream is exhausted but tasks remain active. Now we need to make sure we
171
+ // stop polling the stream and just process tasks.
161
172
Poll :: Ready ( None ) => return Poll :: Pending ,
162
173
Poll :: Pending => return Poll :: Pending ,
163
174
}
@@ -326,6 +337,30 @@ mod tests {
326
337
assert_eq ! ( * entries. lock( ) . unwrap( ) , ( 0 ..5 ) . collect:: <Vec <_>>( ) ) ;
327
338
}
328
339
340
+ #[ test]
341
+ fn test_multiplexer_with_multiple_concurrency_and_less_multiple_futures ( ) {
342
+ let entries = Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ;
343
+ let ( tx, rx) = flume:: bounded ( 10 ) ;
344
+
345
+ // We send 3 futures with a concurrency of 5, to make sure that if the stream returns
346
+ // `Poll::Ready(None)` the system will stop polling from the stream and continue driving
347
+ // the remaining futures.
348
+ for i in 0 ..3 {
349
+ let entries_clone = entries. clone ( ) ;
350
+ tx. send ( future_with ( move || {
351
+ entries_clone. lock ( ) . unwrap ( ) . push ( i) ;
352
+ } ) )
353
+ . unwrap ( ) ;
354
+ }
355
+
356
+ drop ( tx) ;
357
+
358
+ futures:: executor:: block_on ( Multiplexed :: new ( 5 , rx. into_stream ( ) , None ) ) ;
359
+
360
+ // The order of completion is expected to be the same as the order of submission.
361
+ assert_eq ! ( * entries. lock( ) . unwrap( ) , ( 0 ..3 ) . collect:: <Vec <_>>( ) ) ;
362
+ }
363
+
329
364
#[ test]
330
365
fn test_multiplexer_with_multiple_concurrency_and_multiple_futures_from_multiple_threads ( ) {
331
366
let entries = Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ;
0 commit comments