1 //! General purpose TCP server.
2 
3 #![deny(rust_2018_idioms, nonstandard_style)]
4 #![doc(html_logo_url = "https://actix.rs/img/logo.png")]
5 #![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
6 
7 mod accept;
8 mod builder;
9 mod config;
10 mod server;
11 mod service;
12 mod signals;
13 mod socket;
14 mod test_server;
15 mod waker_queue;
16 mod worker;
17 
18 pub use self::builder::ServerBuilder;
19 pub use self::config::{ServiceConfig, ServiceRuntime};
20 pub use self::server::Server;
21 pub use self::service::ServiceFactory;
22 pub use self::test_server::TestServer;
23 
24 #[doc(hidden)]
25 pub use self::socket::FromStream;
26 
27 use std::future::Future;
28 use std::pin::Pin;
29 use std::task::{Context, Poll};
30 
31 /// Socket ID token
32 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
33 pub(crate) struct Token(usize);
34 
35 impl Default for Token {
default() -> Self36     fn default() -> Self {
37         Self::new()
38     }
39 }
40 
41 impl Token {
new() -> Self42     fn new() -> Self {
43         Self(0)
44     }
45 
next(&mut self) -> Token46     pub(crate) fn next(&mut self) -> Token {
47         let token = Token(self.0);
48         self.0 += 1;
49         token
50     }
51 }
52 
53 /// Start server building process
new() -> ServerBuilder54 pub fn new() -> ServerBuilder {
55     ServerBuilder::default()
56 }
57 
58 // a poor man's join future. joined future is only used when starting/stopping the server.
59 // pin_project and pinned futures are overkill for this task.
60 pub(crate) struct JoinAll<T> {
61     fut: Vec<JoinFuture<T>>,
62 }
63 
join_all<T>(fut: Vec<impl Future<Output = T> + 'static>) -> JoinAll<T>64 pub(crate) fn join_all<T>(fut: Vec<impl Future<Output = T> + 'static>) -> JoinAll<T> {
65     let fut = fut
66         .into_iter()
67         .map(|f| JoinFuture::Future(Box::pin(f)))
68         .collect();
69 
70     JoinAll { fut }
71 }
72 
73 enum JoinFuture<T> {
74     Future(Pin<Box<dyn Future<Output = T>>>),
75     Result(Option<T>),
76 }
77 
78 impl<T> Unpin for JoinAll<T> {}
79 
80 impl<T> Future for JoinAll<T> {
81     type Output = Vec<T>;
82 
poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>83     fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
84         let mut ready = true;
85 
86         let this = self.get_mut();
87         for fut in this.fut.iter_mut() {
88             if let JoinFuture::Future(f) = fut {
89                 match f.as_mut().poll(cx) {
90                     Poll::Ready(t) => {
91                         *fut = JoinFuture::Result(Some(t));
92                     }
93                     Poll::Pending => ready = false,
94                 }
95             }
96         }
97 
98         if ready {
99             let mut res = Vec::new();
100             for fut in this.fut.iter_mut() {
101                 if let JoinFuture::Result(f) = fut {
102                     res.push(f.take().unwrap());
103                 }
104             }
105 
106             Poll::Ready(res)
107         } else {
108             Poll::Pending
109         }
110     }
111 }
112 
113 #[cfg(test)]
114 mod test {
115     use super::*;
116 
117     use actix_utils::future::ready;
118 
119     #[actix_rt::test]
test_join_all()120     async fn test_join_all() {
121         let futs = vec![ready(Ok(1)), ready(Err(3)), ready(Ok(9))];
122         let mut res = join_all(futs).await.into_iter();
123         assert_eq!(Ok(1), res.next().unwrap());
124         assert_eq!(Err(3), res.next().unwrap());
125         assert_eq!(Ok(9), res.next().unwrap());
126     }
127 }
128