anvil/
shutdown.rs

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