network/manager/
runner.rs1use crate::manager::stack::Stack;
2use core::time::Duration;
3use embassy_futures::select::select;
4use smoltcp::phy::Device;
5use synchronization::{Arc, blocking_mutex::raw::CriticalSectionRawMutex, signal::Signal};
6
7pub type WakeSignal = Arc<Signal<CriticalSectionRawMutex, ()>>;
9
10pub struct StackRunner<T> {
11 stack: Stack,
12 device: T,
13 wake_signal: WakeSignal,
14}
15
16const MAX_POLL_INTERVAL: Duration = Duration::from_millis(20);
17
18impl<T> StackRunner<T>
19where
20 T: Device,
21{
22 pub fn new(stack: Stack, device: T, wake_signal: WakeSignal) -> Self {
23 Self {
24 stack,
25 device,
26 wake_signal,
27 }
28 }
29
30 pub async fn run(&mut self) -> ! {
31 loop {
32 let next_poll_in = self
33 .stack
34 .with_mutable_no_wake(|stack_inner| {
35 if stack_inner.enabled {
36 stack_inner.poll(&mut self.device)
37 } else {
38 None
39 }
40 })
41 .await;
42
43 let sleep_duration = match next_poll_in {
44 Some(d) if d.is_zero() => {
45 embassy_futures::yield_now().await;
46 continue;
47 }
48 Some(d) => d.min(MAX_POLL_INTERVAL),
49 None => MAX_POLL_INTERVAL,
50 };
51
52 select(task::sleep(sleep_duration), self.wake_signal.wait()).await;
53 }
54 }
55}