@@ -900,6 +900,7 @@ impl ConnectionRef {
900
900
udp_sender : sender,
901
901
runtime,
902
902
send_buffer : Vec :: new ( ) ,
903
+ buffered_transmit : None ,
903
904
observed_external_addr : watch:: Sender :: new ( None ) ,
904
905
} ) ,
905
906
shared : Shared :: default ( ) ,
@@ -1018,6 +1019,8 @@ pub(crate) struct State {
1018
1019
udp_sender : Pin < Box < dyn UdpSender > > ,
1019
1020
runtime : Arc < dyn Runtime > ,
1020
1021
send_buffer : Vec < u8 > ,
1022
+ /// We buffer a transmit when the underlying I/O would block
1023
+ buffered_transmit : Option < proto:: Transmit > ,
1021
1024
/// Our last external address reported by the peer.
1022
1025
pub ( crate ) observed_external_addr : watch:: Sender < Option < SocketAddr > > ,
1023
1026
}
@@ -1030,18 +1033,26 @@ impl State {
1030
1033
let max_datagrams = self . udp_sender . max_transmit_segments ( ) ;
1031
1034
1032
1035
loop {
1033
- self . send_buffer . clear ( ) ;
1034
- self . send_buffer . reserve ( self . inner . current_mtu ( ) as usize ) ;
1035
- let Some ( t) = self
1036
- . inner
1037
- . poll_transmit ( now, max_datagrams, & mut self . send_buffer )
1038
- else {
1039
- break ;
1040
- } ;
1041
-
1042
- transmits += match t. segment_size {
1043
- None => 1 ,
1044
- Some ( s) => ( t. size + s - 1 ) / s, // round up
1036
+ // Retry the last transmit, or get a new one.
1037
+ let t = match self . buffered_transmit . take ( ) {
1038
+ Some ( t) => t,
1039
+ None => {
1040
+ self . send_buffer . clear ( ) ;
1041
+ self . send_buffer . reserve ( self . inner . current_mtu ( ) as usize ) ;
1042
+ match self
1043
+ . inner
1044
+ . poll_transmit ( now, max_datagrams, & mut self . send_buffer )
1045
+ {
1046
+ Some ( t) => {
1047
+ transmits += match t. segment_size {
1048
+ None => 1 ,
1049
+ Some ( s) => ( t. size + s - 1 ) / s, // round up
1050
+ } ;
1051
+ t
1052
+ }
1053
+ None => break ,
1054
+ }
1055
+ }
1045
1056
} ;
1046
1057
1047
1058
let len = t. size ;
@@ -1051,7 +1062,10 @@ impl State {
1051
1062
. as_mut ( )
1052
1063
. poll_send ( & udp_transmit ( & t, & self . send_buffer [ ..len] ) , cx)
1053
1064
{
1054
- Poll :: Pending => return Ok ( true ) ,
1065
+ Poll :: Pending => {
1066
+ self . buffered_transmit = Some ( t) ;
1067
+ return Ok ( false ) ;
1068
+ }
1055
1069
Poll :: Ready ( result) => result?, // propagate errors
1056
1070
}
1057
1071
0 commit comments