anvil/
shutdown.rs

1//! Helper for shutdown signals
2
3use futures::{
4    FutureExt,
5    channel::oneshot,
6    future::{FusedFuture, Shared},
7};
8use std::{
9    pin::Pin,
10    task::{Context, Poll},
11};
12
13/// Future that resolves when the shutdown event has fired
14#[derive(Clone)]
15pub struct Shutdown(Shared<oneshot::Receiver<()>>);
16
17impl Future for Shutdown {
18    type Output = ();
19
20    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
21        let pin = self.get_mut();
22        if pin.0.is_terminated() || pin.0.poll_unpin(cx).is_ready() {
23            Poll::Ready(())
24        } else {
25            Poll::Pending
26        }
27    }
28}
29
30/// Shutdown signal that fires either manually or on drop by closing the channel
31pub struct Signal(oneshot::Sender<()>);
32
33impl Signal {
34    /// Fire the signal manually.
35    pub fn fire(self) -> Result<(), ()> {
36        self.0.send(())
37    }
38}
39
40/// Create a channel pair that's used to propagate shutdown event
41pub fn signal() -> (Signal, Shutdown) {
42    let (sender, receiver) = oneshot::channel();
43    (Signal(sender), Shutdown(receiver.shared()))
44}