# mod.rs - source
Source of the Rust file `/home/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.4.0/src/signal/mod.rs`.
Keywords: rust, rustlang, rust-lang

      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
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100

    //! Asynchronous signal handling for Tokio
    //!
    //! Note that signal handling is in general a very tricky topic and should be
    //! used with great care. This crate attempts to implement 'best practice' for
    //! signal handling, but it should be evaluated for your own applications' needs
    //! to see if it's suitable.
    //!
    //! There are some fundamental limitations of this crate documented on the OS
    //! specific structures, as well.
    //!
    //! # Examples
    //!
    //! Print on "ctrl-c" notification.
    //!
    //! ```rust,no_run
    //! use tokio::signal;
    //!
    //! #[tokio::main]
    //! async fn main() -> Result<(), Box<dyn std::error::Error>> {
    //!     signal::ctrl_c().await?;
    //!     println!("ctrl-c received!");
    //!     Ok(())
    //! }
    //! ```
    //!
    //! Wait for SIGHUP on Unix
    //!
    //! ```rust,no_run
    //! # #[cfg(unix)] {
    //! use tokio::signal::unix::{signal, SignalKind};
    //!
    //! #[tokio::main]
    //! async fn main() -> Result<(), Box<dyn std::error::Error>> {
    //!     // An infinite stream of hangup signals.
    //!     let mut stream = signal(SignalKind::hangup())?;
    //!
    //!     // Print whenever a HUP signal is received
    //!     loop {
    //!         stream.recv().await;
    //!         println!("got signal HUP");
    //!     }
    //! }
    //! # }
    //! ```
    use crate::sync::watch::Receiver;
    use std::task::{Context, Poll};

    mod ctrl_c;
    pub use ctrl_c::ctrl_c;

    mod registry;

    mod os {
        #[cfg(unix)]
        pub(crate) use super::unix::{OsExtraData, OsStorage};

        #[cfg(windows)]
        pub(crate) use super::windows::{OsExtraData, OsStorage};
    }

    pub mod unix;
    pub mod windows;

    mod reusable_box;
    use self::reusable_box::ReusableBoxFuture;

    #[derive(Debug)]
    struct RxFuture {
        inner: ReusableBoxFuture<Receiver<()>>,
    }

    async fn make_future(mut rx: Receiver<()>) -> Receiver<()> {
        match rx.changed().await {
            Ok(()) => rx,
            Err(_) => panic!("signal sender went away"),
        }
    }

    impl RxFuture {
        fn new(rx: Receiver<()>) -> Self {
            Self {
                inner: ReusableBoxFuture::new(make_future(rx)),
            }
        }

        async fn recv(&mut self) -> Option<()> {
            use crate::future::poll_fn;
            poll_fn(|cx| self.poll_recv(cx)).await
        }

        fn poll_recv(&mut self, cx: &mut Context<'_>) -> Poll<Option<()>> {
            match self.inner.poll(cx) {
                Poll::Pending => Poll::Pending,
                Poll::Ready(rx) => {
                    self.inner.set(make_future(rx));
                    Poll::Ready(Some(()))
                }
            }
        }
    }