1pub(crate) mod listener;
2mod select_all;
3pub mod service;
4
5mod infallible;
6
7use alloc::vec::Vec;
8use futures_util::{FutureExt, StreamExt};
9use select_all::SelectAll;
10use service::MethodReply;
11
12use crate::{Call, Connection, Reply, connection::Socket};
13
14#[derive(Debug)]
18pub struct Server<Listener, Service> {
19 listener: Option<Listener>,
20 service: Service,
21}
22
23impl<Listener, Service> Server<Listener, Service>
24where
25 Listener: listener::Listener,
26 Service: service::Service<Listener::Socket>,
27{
28 pub fn new(listener: Listener, service: Service) -> Self {
30 Self {
31 listener: Some(listener),
32 service,
33 }
34 }
35
36 pub async fn run(mut self) -> crate::Result<()> {
61 let mut listener = self.listener.take().unwrap();
62 let mut connections = Vec::new();
63 let mut reply_streams = Vec::<ReplyStream<Service::ReplyStream, Listener::Socket>>::new();
64 let mut reply_stream_futures = Vec::new();
65 let mut read_futures = Vec::new();
68 let mut last_reply_stream_winner = None;
69 let mut last_method_call_winner = None;
70 let mut listener_closed = false;
71
72 loop {
73 if listener_closed && connections.is_empty() && reply_streams.is_empty() {
74 return Ok(());
75 }
76
77 reply_stream_futures.clear();
80 {
81 let reply_streams: &mut Vec<ReplyStream<Service::ReplyStream, Listener::Socket>> =
85 unsafe { &mut *(&mut reply_streams as *mut Vec<_>) };
86 reply_stream_futures.extend(reply_streams.iter_mut().map(|s| s.stream.next()));
87 }
88 let start_index = last_reply_stream_winner.map(|idx| idx + 1);
89 let mut reply_stream_select_all = SelectAll::new(start_index);
90 for future in reply_stream_futures.iter_mut() {
91 reply_stream_select_all.push(future);
92 }
93
94 read_futures.clear();
96 {
97 let connections: &mut Vec<Connection<Listener::Socket>> =
99 unsafe { &mut *(&mut connections as *mut Vec<_>) };
100 read_futures.extend(connections.iter_mut().map(|c| c.receive_call()));
101 }
102 let mut read_select_all = SelectAll::new(last_method_call_winner.map(|idx| idx + 1));
103 for future in &mut read_futures {
104 unsafe {
107 read_select_all.push_unchecked(future);
108 }
109 }
110
111 futures_util::select_biased! {
112 conn = listener.accept().fuse() => match conn? {
114 Some(conn) => connections.push(conn),
115 None => listener_closed = true,
116 },
117 (idx, result) = read_select_all.fuse() => {
119 #[cfg(feature = "std")]
120 let (call, fds) = match result {
121 Ok((call, fds)) => (Ok(call), fds),
122 Err(e) => (Err(e), alloc::vec![]),
123 };
124 #[cfg(not(feature = "std"))]
125 let call = result;
126 last_method_call_winner = Some(idx);
127
128 let mut stream = None;
129 let mut remove = true;
130 match call {
131 Ok(call) => {
132 #[cfg(feature = "std")]
133 let result =
134 self.handle_call(call, &mut connections[idx], fds).await;
135 #[cfg(not(feature = "std"))]
136 let result =
137 self.handle_call(call, &mut connections[idx]).await;
138 match result {
139 Ok(None) => remove = false,
140 Ok(Some(s)) => stream = Some(s),
141 Err(e) => warn!("Error writing to connection: {:?}", e),
142 }
143 }
144 Err(e) => debug!("Error reading from socket: {:?}", e),
145 }
146
147 if stream.is_some() || remove {
148 let conn = connections.swap_remove(idx);
149
150 if let Some(stream) = stream {
151 reply_streams.push(ReplyStream::new(stream, conn));
152 }
153 }
154 }
155 reply = reply_stream_select_all.fuse() => {
157 let (idx, item) = reply;
158 last_reply_stream_winner = Some(idx);
159 let id = reply_streams[idx].conn.id();
160
161 match item {
162 Some(item) => {
163 #[cfg(feature = "std")]
164 let (item, fds) = item;
165 #[cfg(feature = "std")]
166 let send_result = match item {
167 Ok(reply) => reply_streams[idx]
168 .conn
169 .send_reply(&reply, fds)
170 .await,
171 Err(error) => reply_streams[idx]
172 .conn
173 .send_error(&error, fds)
174 .await,
175 };
176 #[cfg(not(feature = "std"))]
177 let send_result = match item {
178 Ok(reply) => reply_streams[idx].conn.send_reply(&reply).await,
179 Err(error) => reply_streams[idx].conn.send_error(&error).await,
180 };
181 if let Err(e) = send_result {
182 warn!("Error writing to client {}: {:?}", id, e);
183 reply_streams.swap_remove(idx);
184 }
185 }
186 None => {
187 trace!("Stream closed for client {}", id);
188 let stream = reply_streams.swap_remove(idx);
189 connections.push(stream.conn);
190 }
191 }
192 }
193 }
194 }
195 }
196
197 async fn handle_call(
198 &mut self,
199 call: Call<Service::MethodCall<'_>>,
200 conn: &mut Connection<Listener::Socket>,
201 #[cfg(feature = "std")] fds: Vec<std::os::fd::OwnedFd>,
202 ) -> crate::Result<Option<Service::ReplyStream>> {
203 let mut stream = None;
204
205 #[cfg(feature = "std")]
206 let (reply, reply_fds) = self.service.handle(&call, conn, fds).await;
207 #[cfg(not(feature = "std"))]
208 let reply = self.service.handle(&call, conn).await;
209
210 match reply {
211 MethodReply::Single(_) | MethodReply::Error(_) if call.oneway() => (),
213 MethodReply::Single(params) => {
214 let reply = Reply::new(params).set_continues(Some(false));
215 #[cfg(feature = "std")]
216 conn.send_reply(&reply, reply_fds).await?;
217 #[cfg(not(feature = "std"))]
218 conn.send_reply(&reply).await?;
219 }
220 #[cfg(feature = "std")]
221 MethodReply::Error(err) => conn.send_error(&err, reply_fds).await?,
222 #[cfg(not(feature = "std"))]
223 MethodReply::Error(err) => conn.send_error(&err).await?,
224 MethodReply::Multi(s) => {
225 trace!("Client {} now turning into a reply stream", conn.id());
226 stream = Some(s)
227 }
228 }
229
230 Ok(stream)
231 }
232}
233
234#[derive(Debug)]
236struct ReplyStream<St, Sock: Socket> {
237 stream: St,
238 conn: Connection<Sock>,
239}
240
241impl<St, Sock> ReplyStream<St, Sock>
242where
243 Sock: Socket,
244{
245 fn new(stream: St, conn: Connection<Sock>) -> Self {
246 Self { stream, conn }
247 }
248}