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