1use core::{
2 future::Future,
3 pin::pin,
4 task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
5};
6use strat9_syscall::call;
7
8const EAGAIN: usize = 11;
9
10pub struct Strat9Runtime;
11
12fn noop_raw_waker() -> RawWaker {
14 fn noop(_: *const ()) {}
16 fn clone(_: *const ()) -> RawWaker {
18 noop_raw_waker()
19 }
20 static VTABLE: RawWakerVTable = RawWakerVTable::new(clone, noop, noop, noop);
21 RawWaker::new(core::ptr::null(), &VTABLE)
22}
23
24#[derive(Debug)]
29pub struct IoError(pub usize);
30
31impl core::fmt::Display for IoError {
32 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
34 write!(f, "IoError({})", self.0)
35 }
36}
37
38impl core::error::Error for IoError {}
39
40impl embedded_io_async::Error for IoError {
41 fn kind(&self) -> embedded_io_async::ErrorKind {
43 embedded_io_async::ErrorKind::Other
44 }
45}
46
47pub struct TcpReadHalf {
52 fd: usize,
53}
54
55pub struct TcpWriteHalf {
56 fd: usize,
57}
58
59impl embedded_io_async::ErrorType for TcpReadHalf {
60 type Error = IoError;
61}
62
63impl embedded_io_async::ErrorType for TcpWriteHalf {
64 type Error = IoError;
65}
66
67impl embedded_io_async::Read for TcpReadHalf {
68 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, IoError> {
70 let mut eagain_spins = 0usize;
71 loop {
72 match call::read(self.fd, buf) {
73 Ok(n) => return Ok(n),
74 Err(e) if e.to_errno() == EAGAIN => {
75 eagain_spins = eagain_spins.saturating_add(1);
76 if eagain_spins % 32 == 0 {
77 crate::net::sleep_ms(1);
78 }
79 let _ = call::sched_yield();
80 continue;
81 }
82 Err(e) => return Err(IoError(e.to_errno())),
83 }
84 }
85 }
86}
87
88impl embedded_io_async::Write for TcpWriteHalf {
89 async fn write(&mut self, buf: &[u8]) -> Result<usize, IoError> {
91 let mut eagain_spins = 0usize;
92 loop {
93 match call::write(self.fd, buf) {
94 Ok(n) => return Ok(n),
95 Err(e) if e.to_errno() == EAGAIN => {
96 eagain_spins = eagain_spins.saturating_add(1);
97 if eagain_spins % 32 == 0 {
98 crate::net::sleep_ms(1);
99 }
100 let _ = call::sched_yield();
101 continue;
102 }
103 Err(e) => return Err(IoError(e.to_errno())),
104 }
105 }
106 }
107
108 async fn flush(&mut self) -> Result<(), IoError> {
110 Ok(())
111 }
112}
113
114pub struct TcpSocket {
119 fd: usize,
120}
121
122impl TcpSocket {
123 pub fn new(fd: usize) -> Self {
125 Self { fd }
126 }
127}
128
129impl picoserve::io::Socket<Strat9Runtime> for TcpSocket {
130 type Error = IoError;
131 type ReadHalf<'a> = TcpReadHalf;
132 type WriteHalf<'a> = TcpWriteHalf;
133
134 fn split(&mut self) -> (TcpReadHalf, TcpWriteHalf) {
136 (TcpReadHalf { fd: self.fd }, TcpWriteHalf { fd: self.fd })
137 }
138
139 async fn abort<T: picoserve::time::Timer<Strat9Runtime>>(
140 self,
141 _timeouts: &picoserve::Timeouts,
142 _timer: &mut T,
143 ) -> Result<(), picoserve::Error<IoError>> {
144 let _ = call::close(self.fd);
145 Ok(())
146 }
147
148 async fn shutdown<T: picoserve::time::Timer<Strat9Runtime>>(
149 self,
150 _timeouts: &picoserve::Timeouts,
151 _timer: &mut T,
152 ) -> Result<(), picoserve::Error<IoError>> {
153 let _ = call::close(self.fd);
154 Ok(())
155 }
156}
157
158pub struct Strat9Timer;
163
164impl picoserve::time::Timer<Strat9Runtime> for Strat9Timer {
165 async fn delay(&self, duration: picoserve::time::Duration) {
167 crate::net::sleep_ms(duration.as_millis());
168 }
169
170 async fn run_with_timeout<F: Future>(
171 &self,
172 duration: picoserve::time::Duration,
173 future: F,
174 ) -> Result<F::Output, picoserve::time::TimeoutError> {
175 let timeout_ns = duration.as_millis().saturating_mul(1_000_000);
176 let start = crate::net::clock_gettime_ns();
177 let deadline = start.saturating_add(timeout_ns);
178 let mut fut = pin!(future);
179
180 let waker = unsafe { Waker::from_raw(noop_raw_waker()) };
182 let mut cx = Context::from_waker(&waker);
183
184 loop {
185 match fut.as_mut().poll(&mut cx) {
186 Poll::Ready(v) => return Ok(v),
187 Poll::Pending => {
188 if crate::net::clock_gettime_ns() >= deadline {
189 return Err(picoserve::time::TimeoutError);
190 }
191 let _ = call::sched_yield();
192 }
193 }
194 }
195 }
196}