The Problem
I was running a webserver (picoserve), but I was only able to run one worker; somewhere in the picoserve code I was running into a panic from SocketSet add function, specifically this panic:
match &mut self.sockets {
ManagedSlice::Borrowed(_) => panic!("adding a socket to a full SocketSet"),
#[cfg(feature = "alloc")]
ManagedSlice::Owned(sockets) => {
sockets.push(SocketStorage { inner: None });
let index = sockets.len() - 1;
put(index, &mut sockets[index], socket)
}
}
The problem, I eventually figured out, was that the network stack created with embassy-net was being initialized with 3 sockets: one for DHCP, one for DNS, and one for the rest of the code.
DHCP & DNS were for the WiFi access point that was also running
// initialize network stack
let (stack, runner) = embassy_net::new(
device,
config,
make_static!(StackResources<3>, StackResources::<3>::new()),
seed,
);
The Solution
// initialize network stack
let (stack, runner) = embassy_net::new(
device,
config,
// 1 socket for dns, 1 for dhcp and 2 for the webserver
// 1 + 1 + 2 = 4 :bicep:
make_static!(StackResources<4>, StackResources::<4>::new()),
seed,
);
It was then possible to spawn two web tasks in main.rs for the webserver:
for task_id in 0..2 {
spawner.spawn(web_task(task_id, stack, app).unwrap());
}
For the super curious, the commit for this fix is on tangled & github.
I don’t know how many sockets my ESP32C5 can do, might be fun to find out, but I have the additional one I needed and that’ll do for now.