signal_handler/
register.rs1use core::ops::{Deref, DerefMut};
2use std::{collections::HashMap, io::Error as IoError};
3
4use channel_sender::{generic::Sender, SendError};
5use signal_hook::{
6 consts::signal::*,
7 low_level::{register, unregister},
8 SigId,
9};
10
11pub type SignalNumber = i32;
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
16pub enum RegisterType {
17 #[cfg(not(windows))]
18 ReloadConfig,
19 WaitForStop,
20 #[cfg(not(windows))]
21 PrintStats,
22}
23
24impl RegisterType {
25 pub fn signal_numbers(&self) -> Vec<SignalNumber> {
26 match self {
27 #[cfg(not(windows))]
28 RegisterType::ReloadConfig => {
29 vec![SIGHUP]
30 }
31 RegisterType::WaitForStop => {
32 let mut list = vec![SIGINT, SIGTERM];
33 #[cfg(not(windows))]
34 {
35 list.push(SIGQUIT);
36 }
37 list
38 }
39 #[cfg(not(windows))]
40 RegisterType::PrintStats => {
41 vec![SIGUSR1]
42 }
43 }
44 }
45}
46
47#[derive(Debug, Clone, Default)]
49pub struct Registers(HashMap<RegisterType, Vec<SignalNumber>>);
50
51impl Deref for Registers {
52 type Target = HashMap<RegisterType, Vec<SignalNumber>>;
53
54 fn deref(&self) -> &Self::Target {
55 &self.0
56 }
57}
58
59impl DerefMut for Registers {
60 fn deref_mut(&mut self) -> &mut Self::Target {
61 &mut self.0
62 }
63}
64
65impl Registers {
67 pub fn new() -> Self {
68 Self::default()
69 }
70
71 #[cfg(not(windows))]
72 pub fn insert_reload_config(&mut self) -> Option<Vec<SignalNumber>> {
73 self.insert(
74 RegisterType::ReloadConfig,
75 RegisterType::ReloadConfig.signal_numbers(),
76 )
77 }
78
79 pub fn insert_wait_for_stop(&mut self) -> Option<Vec<SignalNumber>> {
80 self.insert(
81 RegisterType::WaitForStop,
82 RegisterType::WaitForStop.signal_numbers(),
83 )
84 }
85
86 #[cfg(not(windows))]
87 pub fn insert_print_stats(&mut self) -> Option<Vec<SignalNumber>> {
88 self.insert(
89 RegisterType::PrintStats,
90 RegisterType::PrintStats.signal_numbers(),
91 )
92 }
93}
94
95pub type RegisterError = IoError;
97
98impl Registers {
99 pub fn register<Tx>(self, sender: Tx) -> Result<HashMap<SignalNumber, SigId>, RegisterError>
100 where
101 Tx: Sender<RegisterType> + Clone + Send + Sync + 'static,
102 {
103 let mut map = HashMap::new();
104
105 for (tp, signal_numbers) in &self.0 {
106 for signal_number in signal_numbers {
107 let sender = sender.clone();
108
109 let signal_number = *signal_number;
110 let tp = *tp;
111
112 let sig_id = unsafe {
113 register(signal_number, move || {
114 match sender.send(tp) {
115 Ok(_) => {}
116 Err(SendError::Full(_)) => {
117 }
119 Err(SendError::Closed(_)) | Err(SendError::Disconnected(_)) => {
120 }
122 }
123 })
124 }?;
125
126 map.insert(signal_number, sig_id);
127 }
128 }
129
130 Ok(map)
131 }
132
133 pub fn unregister(sig_ids: &[SigId]) {
134 for sig_id in sig_ids {
135 unregister(*sig_id);
136 }
137 }
138}