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
extern crate nix;
#[macro_use]
extern crate lazy_static;

use std::sync::{ONCE_INIT, Once, Arc};
use std::sync::atomic::{AtomicBool, Ordering, ATOMIC_BOOL_INIT};
use nix::sys::signal::{self, SigAction};

static INIT: Once = ONCE_INIT;
static mut SIG_ACTION: Option<SigAction> = None;

lazy_static! {
    static ref CLOSED: Arc<AtomicBool> = Arc::new(ATOMIC_BOOL_INIT);
}

extern "C" fn when_exit(_: i32) {
    CLOSED.store(true, Ordering::Relaxed);
}

pub struct Closer;

impl Closer {
    pub fn init() -> Closer {
        INIT.call_once(|| {
            let sig_action = signal::SigAction::new(
                signal::SigHandler::Handler(when_exit),
                signal::SaFlags::empty(),
                signal::SigSet::empty(),
            );

            unsafe {
                signal::sigaction(signal::SIGINT, &sig_action).unwrap();
                signal::sigaction(signal::SIGTERM, &sig_action).unwrap();
                SIG_ACTION = Some(sig_action);
            }
        });

        Closer
    }

    pub fn is_closed(&self) -> bool {
        CLOSED.load(Ordering::Relaxed)
    }

    pub fn closed(&self) -> Arc<AtomicBool> {
        CLOSED.clone()
    }
}