Skip to content

Commit

Permalink
net: Notify clients that tried to send that space is now available (#653
Browse files Browse the repository at this point in the history
)
  • Loading branch information
jgallagher committed Jul 14, 2022
1 parent a7d0687 commit 7cdd4b8
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 13 deletions.
2 changes: 2 additions & 0 deletions task/net-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ pub enum NetError {
QueueEmpty = 1,
NotYours = 2,
InvalidVLan = 3,
QueueFull = 4,
Other = 5,
}

#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
Expand Down
14 changes: 9 additions & 5 deletions task/net/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ impl<'a> ServerStorage<'a> {
/// State for the running network server.
pub struct ServerImpl<'a> {
socket_handles: [SocketHandle; SOCKET_COUNT],
client_waiting_to_send: [bool; SOCKET_COUNT],
iface: Interface<'a, &'a eth::Ethernet>,
bsp: crate::bsp::Bsp,
}
Expand Down Expand Up @@ -92,6 +93,7 @@ impl<'a> ServerImpl<'a> {

Self {
socket_handles,
client_waiting_to_send: [false; SOCKET_COUNT],
iface,
bsp,
}
Expand All @@ -109,7 +111,9 @@ impl<'a> ServerImpl<'a> {
// TODO making every packet O(n) in the number of sockets is super
// lame; provide a Waker to fix this.
for i in 0..SOCKET_COUNT {
if self.get_socket_mut(i).unwrap().can_recv() {
let want_to_send = self.client_waiting_to_send[i];
let socket = self.get_socket_mut(i).unwrap();
if socket.can_recv() || (want_to_send && socket.can_send()) {
// Make sure the owner knows about this. This can
// technically cause spurious wakeups if the owner is
// already waiting in our incoming queue to recv. Maybe we
Expand Down Expand Up @@ -224,16 +228,16 @@ impl idl::InOrderNetImpl for ServerImpl<'_> {
payload
.read_range(0..payload.len(), buf)
.map_err(|_| RequestError::went_away())?;
self.client_waiting_to_send[socket_index] = false;
Ok(())
}
Err(smoltcp::Error::Exhausted) => {
// TODO this is not quite right
Err(NetError::QueueEmpty.into())
self.client_waiting_to_send[socket_index] = true;
Err(NetError::QueueFull.into())
}
Err(_e) => {
// uhhhh TODO
// TODO this is not quite right
Err(NetError::QueueEmpty.into())
Err(NetError::Other.into())
}
}
}
Expand Down
18 changes: 11 additions & 7 deletions task/net/src/vlan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ pub struct ServerImpl<'a> {
eth: &'a eth::Ethernet,

socket_handles: [[SocketHandle; SOCKET_COUNT]; VLAN_COUNT],
client_waiting_to_send: [bool; SOCKET_COUNT],
ifaces: [Interface<'a, VLanEthernet<'a>>; VLAN_COUNT],
bsp: crate::bsp::Bsp,
}
Expand Down Expand Up @@ -205,6 +206,7 @@ impl<'a> ServerImpl<'a> {
let ifaces = ifaces.map(|e| e.unwrap());
Self {
eth: &storage.eth,
client_waiting_to_send: [false; SOCKET_COUNT],
socket_handles,
ifaces,
bsp,
Expand All @@ -225,9 +227,11 @@ impl<'a> ServerImpl<'a> {
/// we don't know which VLAN it will write to.
pub fn wake_sockets(&mut self) {
for i in 0..SOCKET_COUNT {
if (0..VLAN_COUNT)
.any(|v| self.get_socket_mut(i, v).unwrap().can_recv())
{
if (0..VLAN_COUNT).any(|v| {
let want_to_send = self.client_waiting_to_send[i];
let socket = self.get_socket_mut(i, v).unwrap();
socket.can_recv() || (want_to_send && socket.can_send())
}) {
let (task_id, notification) = generated::SOCKET_OWNERS[i];
let task_id = sys_refresh_task_id(task_id);
sys_post(task_id, notification);
Expand Down Expand Up @@ -352,16 +356,16 @@ impl idl::InOrderNetImpl for ServerImpl<'_> {
payload
.read_range(0..payload.len(), buf)
.map_err(|_| RequestError::went_away())?;
self.client_waiting_to_send[socket_index] = false;
Ok(())
}
Err(smoltcp::Error::Exhausted) => {
// TODO this is not quite right
Err(NetError::QueueEmpty.into())
self.client_waiting_to_send[socket_index] = true;
Err(NetError::QueueFull.into())
}
Err(_e) => {
// uhhhh TODO
// TODO this is not quite right
Err(NetError::QueueEmpty.into())
Err(NetError::Other.into())
}
}
}
Expand Down
19 changes: 18 additions & 1 deletion task/udpecho/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,31 @@ fn main() -> ! {
// Now we know how many bytes to return.
let tx_bytes = &rx_data_buf[..meta.size as usize];

net.send_packet(SOCKET, meta, tx_bytes).unwrap();
loop {
match net.send_packet(SOCKET, meta, tx_bytes) {
Ok(()) => break,
Err(NetError::QueueFull) => {
// Our outgoing queue is full; wait for space.
sys_recv_closed(&mut [], 1, TaskId::KERNEL)
.unwrap();
}
Err(NetError::NotYours) => panic!(),
Err(NetError::InvalidVLan) => panic!(),
Err(NetError::Other) => panic!(),
// `send_packet()` can't return QueueEmpty
Err(NetError::QueueEmpty) => unreachable!(),
}
}
}
Err(NetError::QueueEmpty) => {
// Our incoming queue is empty. Wait for more packets.
sys_recv_closed(&mut [], 1, TaskId::KERNEL).unwrap();
}
Err(NetError::NotYours) => panic!(),
Err(NetError::InvalidVLan) => panic!(),
Err(NetError::Other) => panic!(),
// `recv_packet()` can't return QueueFull
Err(NetError::QueueFull) => unreachable!(),
}

// Try again.
Expand Down

0 comments on commit 7cdd4b8

Please sign in to comment.