Keep dispatching packets from a socket as long as there are any.

Typically, the poll function is used as a part of a larger RTOS.
If we only dispatch one packet per socket per poll() call,
then we have to wait for a complete scheduler roundtrip,
which is potentially a lot of time, and as a result we are
not filling the peer's window efficiently.
This commit is contained in:
whitequark 2017-09-22 17:55:49 +00:00
parent b90cee43bb
commit 05a480575c
1 changed files with 31 additions and 29 deletions

View File

@ -165,36 +165,38 @@ impl<'a, 'b, 'c, DeviceT: Device + 'a> Interface<'a, 'b, 'c, DeviceT> {
let mut limits = self.device.limits();
limits.max_transmission_unit -= EthernetFrame::<&[u8]>::header_len();
for socket in sockets.iter_mut() {
let mut device_result = Ok(());
let socket_result =
match socket {
&mut Socket::Raw(ref mut socket) =>
socket.dispatch(|response| {
device_result = self.dispatch(timestamp, Packet::Raw(response));
device_result
}),
&mut Socket::Udp(ref mut socket) =>
socket.dispatch(|response| {
device_result = self.dispatch(timestamp, Packet::Udp(response));
device_result
}),
&mut Socket::Tcp(ref mut socket) =>
socket.dispatch(timestamp, &limits, |response| {
device_result = self.dispatch(timestamp, Packet::Tcp(response));
device_result
}),
&mut Socket::__Nonexhaustive => unreachable!()
};
match (device_result, socket_result) {
(Err(Error::Unaddressable), _) => break, // no one to transmit to
(Err(Error::Exhausted), _) => break, // nowhere to transmit
(Ok(()), Err(Error::Exhausted)) => (), // nothing to transmit
(Err(err), _) | (_, Err(err)) => {
net_debug!("cannot dispatch egress packet: {}", err);
return Err(err)
'iface: for socket in sockets.iter_mut() {
'socket: loop {
let mut device_result = Ok(());
let socket_result =
match socket {
&mut Socket::Raw(ref mut socket) =>
socket.dispatch(|response| {
device_result = self.dispatch(timestamp, Packet::Raw(response));
device_result
}),
&mut Socket::Udp(ref mut socket) =>
socket.dispatch(|response| {
device_result = self.dispatch(timestamp, Packet::Udp(response));
device_result
}),
&mut Socket::Tcp(ref mut socket) =>
socket.dispatch(timestamp, &limits, |response| {
device_result = self.dispatch(timestamp, Packet::Tcp(response));
device_result
}),
&mut Socket::__Nonexhaustive => unreachable!()
};
match (device_result, socket_result) {
(Err(Error::Exhausted), _) => break 'iface, // nowhere to transmit
(Err(Error::Unaddressable), _) => break 'socket, // no one to transmit to
(Ok(()), Err(Error::Exhausted)) => break 'socket, // nothing to transmit
(_, Err(err)) => {
net_debug!("cannot dispatch egress packet: {}", err);
return Err(err)
}
(_, Ok(())) => ()
}
(Ok(()), Ok(())) => ()
}
}