yz_server_executor/
lib.rs1#![forbid(unsafe_code)]
2
3pub use async_executor::Executor;
4use event_listener::Event;
5use futures_lite::future::block_on as fblon;
6use std::sync::Arc;
7
8pub struct ServerExecutor {
9 ex: Arc<Executor<'static>>,
11
12 shutdown: Event,
13}
14
15#[cfg(feature = "num_cpus")]
16impl Default for ServerExecutor {
17 #[inline]
18 fn default() -> Self {
19 Self::new()
20 }
21}
22
23impl ServerExecutor {
24 #[cfg(feature = "num_cpus")]
25 #[inline]
26 pub fn new() -> Self {
27 Self::with_threads(num_cpus::get())
28 }
29
30 pub fn with_threads(n: usize) -> Self {
31 let ret = Self {
32 ex: Arc::new(Executor::new()),
33 shutdown: Event::new(),
34 };
35
36 for _ in 0..n {
37 let ex = ret.ex.clone();
38 let listener = ret.shutdown.listen();
39 std::thread::Builder::new()
40 .name("yxd-srvexec-worker".to_string())
41 .spawn(move || fblon(ex.run(listener)))
42 .expect("unable to spawn worker threads");
43 }
44
45 ret
46 }
47
48 #[inline]
50 pub fn block_on<'x, F, I, R>(&'x self, f: F) -> R
51 where
52 F: FnOnce(&'x Arc<Executor<'static>>) -> I,
53 I: std::future::Future<Output = R> + 'x,
54 R: 'x,
55 {
56 fblon(f(&self.ex))
57 }
58}
59
60impl Drop for ServerExecutor {
61 fn drop(&mut self) {
62 self.shutdown.notify(usize::MAX);
66 }
67}