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
16impl<T> StackRunner<T>
17where
18 T: Device,
19{
20 pub fn new(stack: Stack, device: T, wake_signal: WakeSignal) -> Self {
21 Self {
22 stack,
23 device,
24 wake_signal,
25 }
26 }
27
28 pub async fn run(&mut self) -> ! {
29 loop {
30 let next_poll_in = self
31 .stack
32 .with_mutable_no_wake(|stack_inner| {
33 if stack_inner.enabled {
34 stack_inner.poll(&mut self.device)
35 } else {
36 None
37 }
38 })
39 .await;
40
41 let sleep_duration = match next_poll_in {
42 Some(d) if d.is_zero() => {
43 embassy_futures::yield_now().await;
44 continue;
45 }
46 Some(d) => d,
47 None => Duration::from_millis(200),
48 };
49
50 select(task::sleep(sleep_duration), self.wake_signal.wait()).await;
51 }
52 }
53}