2019-11-14 13:38:24 +01:00
|
|
|
use std::future::Future;
|
2018-12-11 06:06:54 +01:00
|
|
|
use std::io;
|
2019-11-14 13:38:24 +01:00
|
|
|
use std::pin::Pin;
|
|
|
|
use std::task::{Context, Poll};
|
2018-12-11 06:06:54 +01:00
|
|
|
|
|
|
|
use actix_rt::spawn;
|
2019-11-14 13:38:24 +01:00
|
|
|
use futures::future::LocalBoxFuture;
|
|
|
|
use futures::stream::{futures_unordered, FuturesUnordered, LocalBoxStream};
|
|
|
|
use futures::{FutureExt, Stream, StreamExt, TryFutureExt, TryStream, TryStreamExt};
|
|
|
|
use tokio_net::signal::unix::signal;
|
2018-12-11 06:06:54 +01:00
|
|
|
|
|
|
|
use crate::server::Server;
|
|
|
|
|
|
|
|
/// Different types of process signals
|
|
|
|
#[derive(PartialEq, Clone, Copy, Debug)]
|
|
|
|
pub(crate) enum Signal {
|
|
|
|
/// SIGHUP
|
|
|
|
Hup,
|
|
|
|
/// SIGINT
|
|
|
|
Int,
|
|
|
|
/// SIGTERM
|
|
|
|
Term,
|
|
|
|
/// SIGQUIT
|
|
|
|
Quit,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) struct Signals {
|
|
|
|
srv: Server,
|
|
|
|
#[cfg(not(unix))]
|
|
|
|
stream: SigStream,
|
|
|
|
#[cfg(unix)]
|
|
|
|
streams: Vec<SigStream>,
|
|
|
|
}
|
|
|
|
|
2019-11-14 13:38:24 +01:00
|
|
|
type SigStream = LocalBoxStream<'static, Result<Signal, io::Error>>;
|
2018-12-11 06:06:54 +01:00
|
|
|
|
|
|
|
impl Signals {
|
|
|
|
pub(crate) fn start(srv: Server) {
|
|
|
|
let fut = {
|
|
|
|
#[cfg(not(unix))]
|
|
|
|
{
|
2019-11-14 13:38:24 +01:00
|
|
|
tokio_net::signal::ctrl_c()
|
2018-12-11 23:03:06 +01:00
|
|
|
.map_err(|_| ())
|
|
|
|
.and_then(move |stream| Signals {
|
|
|
|
srv,
|
|
|
|
stream: Box::new(stream.map(|_| Signal::Int)),
|
|
|
|
})
|
2018-12-11 06:06:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(unix)]
|
|
|
|
{
|
2019-11-14 13:38:24 +01:00
|
|
|
use tokio_net::signal::unix;
|
|
|
|
|
|
|
|
let mut sigs: Vec<_> = Vec::new();
|
|
|
|
|
|
|
|
let mut SIG_MAP = [
|
|
|
|
(
|
|
|
|
tokio_net::signal::unix::SignalKind::interrupt(),
|
|
|
|
Signal::Int,
|
|
|
|
),
|
|
|
|
(tokio_net::signal::unix::SignalKind::hangup(), Signal::Hup),
|
|
|
|
(
|
|
|
|
tokio_net::signal::unix::SignalKind::terminate(),
|
|
|
|
Signal::Term,
|
|
|
|
),
|
|
|
|
(tokio_net::signal::unix::SignalKind::quit(), Signal::Quit),
|
|
|
|
];
|
|
|
|
|
|
|
|
for (kind, sig) in SIG_MAP.into_iter() {
|
|
|
|
let sig = sig.clone();
|
|
|
|
let fut = signal(*kind).unwrap();
|
|
|
|
sigs.push(fut.map(move |_| Ok(sig)).boxed_local());
|
|
|
|
}
|
|
|
|
/* TODO: Finish rewriting this
|
|
|
|
sigs.push(
|
|
|
|
tokio_net::signal::unix::signal(tokio_net::signal::si).unwrap()
|
|
|
|
.map(|stream| {
|
|
|
|
let s: SigStream = Box::new(stream.map(|_| Signal::Int));
|
|
|
|
s
|
|
|
|
}).boxed()
|
|
|
|
);
|
|
|
|
sigs.push(
|
|
|
|
|
|
|
|
tokio_net::signal::unix::signal(tokio_net::signal::unix::SignalKind::hangup()).unwrap()
|
|
|
|
.map(|stream: unix::Signal| {
|
2018-12-11 06:06:54 +01:00
|
|
|
let s: SigStream = Box::new(stream.map(|_| Signal::Hup));
|
|
|
|
s
|
2019-11-14 13:38:24 +01:00
|
|
|
}).boxed()
|
|
|
|
);
|
|
|
|
sigs.push(
|
|
|
|
tokio_net::signal::unix::signal(
|
|
|
|
tokio_net::signal::unix::SignalKind::terminate()
|
|
|
|
).unwrap()
|
|
|
|
.map(|stream| {
|
2018-12-11 06:06:54 +01:00
|
|
|
let s: SigStream = Box::new(stream.map(|_| Signal::Term));
|
|
|
|
s
|
2019-11-14 13:38:24 +01:00
|
|
|
}).boxed(),
|
|
|
|
);
|
|
|
|
sigs.push(
|
|
|
|
tokio_net::signal::unix::signal(
|
|
|
|
tokio_net::signal::unix::SignalKind::quit()
|
|
|
|
).unwrap()
|
|
|
|
.map(|stream| {
|
2018-12-11 06:06:54 +01:00
|
|
|
let s: SigStream = Box::new(stream.map(|_| Signal::Quit));
|
|
|
|
s
|
2019-11-14 13:38:24 +01:00
|
|
|
}).boxed()
|
|
|
|
);
|
|
|
|
*/
|
|
|
|
|
|
|
|
Signals { srv, streams: sigs }
|
2018-12-11 06:06:54 +01:00
|
|
|
}
|
|
|
|
};
|
2019-11-14 13:38:24 +01:00
|
|
|
spawn(async {});
|
2018-12-11 06:06:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Future for Signals {
|
2019-11-14 13:38:24 +01:00
|
|
|
type Output = ();
|
|
|
|
|
|
|
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
|
|
|
unimplemented!()
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2018-12-11 06:06:54 +01:00
|
|
|
type Item = ();
|
|
|
|
type Error = ();
|
|
|
|
|
|
|
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
|
|
|
#[cfg(not(unix))]
|
|
|
|
loop {
|
|
|
|
match self.stream.poll() {
|
|
|
|
Ok(Async::Ready(None)) | Err(_) => return Ok(Async::Ready(())),
|
|
|
|
Ok(Async::Ready(Some(sig))) => self.srv.signal(sig),
|
|
|
|
Ok(Async::NotReady) => return Ok(Async::NotReady),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#[cfg(unix)]
|
|
|
|
{
|
|
|
|
for s in &mut self.streams {
|
|
|
|
loop {
|
|
|
|
match s.poll() {
|
|
|
|
Ok(Async::Ready(None)) | Err(_) => return Ok(Async::Ready(())),
|
|
|
|
Ok(Async::NotReady) => break,
|
|
|
|
Ok(Async::Ready(Some(sig))) => self.srv.signal(sig),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(Async::NotReady)
|
|
|
|
}
|
|
|
|
}
|
2019-11-14 13:38:24 +01:00
|
|
|
*/
|
2018-12-11 06:06:54 +01:00
|
|
|
}
|