@@ -286,7 +286,8 @@ struct Active<T> {
286
286
stream_receivers : SelectAll < TaggedStream < StreamId , mpsc:: Receiver < StreamCommand > > > ,
287
287
no_streams_waker : Option < Waker > ,
288
288
289
- pending_frames : VecDeque < Frame < ( ) > > ,
289
+ pending_read_frame : Option < Frame < ( ) > > ,
290
+ pending_write_frame : Option < Frame < ( ) > > ,
290
291
new_outbound_stream_waker : Option < Waker > ,
291
292
292
293
rtt : rtt:: Rtt ,
@@ -360,7 +361,8 @@ impl<T: AsyncRead + AsyncWrite + Unpin> Active<T> {
360
361
Mode :: Client => 1 ,
361
362
Mode :: Server => 2 ,
362
363
} ,
363
- pending_frames : VecDeque :: default ( ) ,
364
+ pending_read_frame : None ,
365
+ pending_write_frame : None ,
364
366
new_outbound_stream_waker : None ,
365
367
rtt : rtt:: Rtt :: new ( ) ,
366
368
accumulated_max_stream_windows : Default :: default ( ) ,
@@ -369,7 +371,12 @@ impl<T: AsyncRead + AsyncWrite + Unpin> Active<T> {
369
371
370
372
/// Gracefully close the connection to the remote.
371
373
fn close ( self ) -> Closing < T > {
372
- Closing :: new ( self . stream_receivers , self . pending_frames , self . socket )
374
+ let pending_frames = self
375
+ . pending_read_frame
376
+ . into_iter ( )
377
+ . chain ( self . pending_write_frame )
378
+ . collect :: < VecDeque < Frame < ( ) > > > ( ) ;
379
+ Closing :: new ( self . stream_receivers , pending_frames, self . socket )
373
380
}
374
381
375
382
/// Cleanup all our resources.
@@ -392,7 +399,13 @@ impl<T: AsyncRead + AsyncWrite + Unpin> Active<T> {
392
399
continue ;
393
400
}
394
401
395
- if let Some ( frame) = self . pending_frames . pop_front ( ) {
402
+ // Privilege pending `Pong` and `GoAway` `Frame`s
403
+ // over `Frame`s from the receivers.
404
+ if let Some ( frame) = self
405
+ . pending_read_frame
406
+ . take ( )
407
+ . or_else ( || self . pending_write_frame . take ( ) )
408
+ {
396
409
self . socket . start_send_unpin ( frame) ?;
397
410
continue ;
398
411
}
@@ -403,36 +416,63 @@ impl<T: AsyncRead + AsyncWrite + Unpin> Active<T> {
403
416
Poll :: Pending => { }
404
417
}
405
418
406
- match self . stream_receivers . poll_next_unpin ( cx) {
407
- Poll :: Ready ( Some ( ( _, Some ( StreamCommand :: SendFrame ( frame) ) ) ) ) => {
408
- self . on_send_frame ( frame) ;
409
- continue ;
410
- }
411
- Poll :: Ready ( Some ( ( id, Some ( StreamCommand :: CloseStream { ack } ) ) ) ) => {
412
- self . on_close_stream ( id, ack) ;
413
- continue ;
414
- }
415
- Poll :: Ready ( Some ( ( id, None ) ) ) => {
416
- self . on_drop_stream ( id) ;
417
- continue ;
418
- }
419
- Poll :: Ready ( None ) => {
420
- self . no_streams_waker = Some ( cx. waker ( ) . clone ( ) ) ;
419
+ if self . pending_write_frame . is_none ( ) {
420
+ match self . stream_receivers . poll_next_unpin ( cx) {
421
+ Poll :: Ready ( Some ( ( _, Some ( StreamCommand :: SendFrame ( frame) ) ) ) ) => {
422
+ log:: trace!(
423
+ "{}/{}: sending: {}" ,
424
+ self . id,
425
+ frame. header( ) . stream_id( ) ,
426
+ frame. header( )
427
+ ) ;
428
+ self . pending_write_frame . replace ( frame. into ( ) ) ;
429
+ continue ;
430
+ }
431
+ Poll :: Ready ( Some ( ( id, Some ( StreamCommand :: CloseStream { ack } ) ) ) ) => {
432
+ log:: trace!( "{}/{}: sending close" , self . id, id) ;
433
+ self . pending_write_frame
434
+ . replace ( Frame :: close_stream ( id, ack) . into ( ) ) ;
435
+ continue ;
436
+ }
437
+ Poll :: Ready ( Some ( ( id, None ) ) ) => {
438
+ if let Some ( frame) = self . on_drop_stream ( id) {
439
+ log:: trace!( "{}/{}: sending: {}" , self . id, id, frame. header( ) ) ;
440
+ self . pending_write_frame . replace ( frame) ;
441
+ } ;
442
+ continue ;
443
+ }
444
+ Poll :: Ready ( None ) => {
445
+ self . no_streams_waker = Some ( cx. waker ( ) . clone ( ) ) ;
446
+ }
447
+ Poll :: Pending => { }
421
448
}
422
- Poll :: Pending => { }
423
449
}
424
450
425
- match self . socket . poll_next_unpin ( cx) {
426
- Poll :: Ready ( Some ( frame) ) => {
427
- if let Some ( stream) = self . on_frame ( frame?) ? {
428
- return Poll :: Ready ( Ok ( stream) ) ;
451
+ if self . pending_read_frame . is_none ( ) {
452
+ match self . socket . poll_next_unpin ( cx) {
453
+ Poll :: Ready ( Some ( frame) ) => {
454
+ match self . on_frame ( frame?) ? {
455
+ Action :: None => { }
456
+ Action :: New ( stream) => {
457
+ log:: trace!( "{}: new inbound {} of {}" , self . id, stream, self ) ;
458
+ return Poll :: Ready ( Ok ( stream) ) ;
459
+ }
460
+ Action :: Ping ( f) => {
461
+ log:: trace!( "{}/{}: pong" , self . id, f. header( ) . stream_id( ) ) ;
462
+ self . pending_read_frame . replace ( f. into ( ) ) ;
463
+ }
464
+ Action :: Terminate ( f) => {
465
+ log:: trace!( "{}: sending term" , self . id) ;
466
+ self . pending_read_frame . replace ( f. into ( ) ) ;
467
+ }
468
+ }
469
+ continue ;
429
470
}
430
- continue ;
431
- }
432
- Poll :: Ready ( None ) => {
433
- return Poll :: Ready ( Err ( ConnectionError :: Closed ) ) ;
471
+ Poll :: Ready ( None ) => {
472
+ return Poll :: Ready ( Err ( ConnectionError :: Closed ) ) ;
473
+ }
474
+ Poll :: Pending => { }
434
475
}
435
- Poll :: Pending => { }
436
476
}
437
477
438
478
// If we make it this far, at least one of the above must have registered a waker.
@@ -463,23 +503,7 @@ impl<T: AsyncRead + AsyncWrite + Unpin> Active<T> {
463
503
Poll :: Ready ( Ok ( stream) )
464
504
}
465
505
466
- fn on_send_frame ( & mut self , frame : Frame < Either < Data , WindowUpdate > > ) {
467
- log:: trace!(
468
- "{}/{}: sending: {}" ,
469
- self . id,
470
- frame. header( ) . stream_id( ) ,
471
- frame. header( )
472
- ) ;
473
- self . pending_frames . push_back ( frame. into ( ) ) ;
474
- }
475
-
476
- fn on_close_stream ( & mut self , id : StreamId , ack : bool ) {
477
- log:: trace!( "{}/{}: sending close" , self . id, id) ;
478
- self . pending_frames
479
- . push_back ( Frame :: close_stream ( id, ack) . into ( ) ) ;
480
- }
481
-
482
- fn on_drop_stream ( & mut self , stream_id : StreamId ) {
506
+ fn on_drop_stream ( & mut self , stream_id : StreamId ) -> Option < Frame < ( ) > > {
483
507
let s = self . streams . remove ( & stream_id) . expect ( "stream not found" ) ;
484
508
485
509
log:: trace!( "{}: removing dropped stream {}" , self . id, stream_id) ;
@@ -525,10 +549,7 @@ impl<T: AsyncRead + AsyncWrite + Unpin> Active<T> {
525
549
}
526
550
frame
527
551
} ;
528
- if let Some ( f) = frame {
529
- log:: trace!( "{}/{}: sending: {}" , self . id, stream_id, f. header( ) ) ;
530
- self . pending_frames . push_back ( f. into ( ) ) ;
531
- }
552
+ frame. map ( Into :: into)
532
553
}
533
554
534
555
/// Process the result of reading from the socket.
@@ -537,7 +558,7 @@ impl<T: AsyncRead + AsyncWrite + Unpin> Active<T> {
537
558
/// and return a corresponding error, which terminates the connection.
538
559
/// Otherwise we process the frame and potentially return a new `Stream`
539
560
/// if one was opened by the remote.
540
- fn on_frame ( & mut self , frame : Frame < ( ) > ) -> Result < Option < Stream > > {
561
+ fn on_frame ( & mut self , frame : Frame < ( ) > ) -> Result < Action > {
541
562
log:: trace!( "{}: received: {}" , self . id, frame. header( ) ) ;
542
563
543
564
if frame. header ( ) . flags ( ) . contains ( header:: ACK )
@@ -560,23 +581,7 @@ impl<T: AsyncRead + AsyncWrite + Unpin> Active<T> {
560
581
Tag :: Ping => self . on_ping ( & frame. into_ping ( ) ) ,
561
582
Tag :: GoAway => return Err ( ConnectionError :: Closed ) ,
562
583
} ;
563
- match action {
564
- Action :: None => { }
565
- Action :: New ( stream) => {
566
- log:: trace!( "{}: new inbound {} of {}" , self . id, stream, self ) ;
567
- return Ok ( Some ( stream) ) ;
568
- }
569
- Action :: Ping ( f) => {
570
- log:: trace!( "{}/{}: pong" , self . id, f. header( ) . stream_id( ) ) ;
571
- self . pending_frames . push_back ( f. into ( ) ) ;
572
- }
573
- Action :: Terminate ( f) => {
574
- log:: trace!( "{}: sending term" , self . id) ;
575
- self . pending_frames . push_back ( f. into ( ) ) ;
576
- }
577
- }
578
-
579
- Ok ( None )
584
+ Ok ( action)
580
585
}
581
586
582
587
fn on_data ( & mut self , frame : Frame < Data > ) -> Action {
0 commit comments