gateway_runtime/
shutdown.rs1use core::future::Future;
12use core::pin::Pin;
13use core::task::{Context, Poll};
14
15#[cfg(feature = "std")]
16use tokio::signal;
17
18pub struct ShutdownSignal {
20 #[cfg(feature = "std")]
21 inner: Pin<Box<dyn Future<Output = ()> + Send + Sync>>,
22}
23
24impl ShutdownSignal {
25 pub fn new() -> Self {
27 #[cfg(feature = "std")]
28 {
29 let fut = async {
30 let ctrl_c = async {
31 signal::ctrl_c()
32 .await
33 .expect("failed to install Ctrl+C handler");
34 };
35
36 #[cfg(unix)]
37 let terminate = async {
38 signal::unix::signal(signal::unix::SignalKind::terminate())
39 .expect("failed to install signal handler")
40 .recv()
41 .await;
42 };
43
44 #[cfg(not(unix))]
45 let terminate = std::future::pending::<()>();
46
47 tokio::select! {
48 _ = ctrl_c => {},
49 _ = terminate => {},
50 }
51 };
52 Self {
53 inner: Box::pin(fut),
54 }
55 }
56 #[cfg(not(feature = "std"))]
57 {
58 Self {}
59 }
60 }
61}
62
63impl Future for ShutdownSignal {
64 type Output = ();
65
66 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
67 #[cfg(feature = "std")]
68 return self.inner.as_mut().poll(cx);
69 #[cfg(not(feature = "std"))]
70 Poll::Pending
71 }
72}
73
74pub async fn wait_for_signal() {
76 ShutdownSignal::new().await
77}