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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
extern crate libc;
use super::daemon::*;
use std::io::{Error, ErrorKind};
use std::sync::mpsc::channel;
use std::sync::mpsc::Receiver;
use std::sync::mpsc::Sender;
declare_singleton!(
singleton,
DaemonHolder,
DaemonHolder {
holder: 0 as *mut DaemonStatic
}
);
struct DaemonHolder {
holder: *mut DaemonStatic,
}
struct DaemonStatic {
holder: Box<DaemonFunc>,
}
trait DaemonFunc {
fn exec(&mut self) -> Result<(), Error>;
fn send(&mut self, state: State) -> Result<(), Error>;
fn take_tx(&mut self) -> Option<Sender<State>>;
}
struct DaemonFuncHolder<F: FnOnce(Receiver<State>)> {
tx: Option<Sender<State>>,
func: Option<(F, Receiver<State>)>,
}
impl<F: FnOnce(Receiver<State>)> DaemonFunc for DaemonFuncHolder<F> {
fn exec(&mut self) -> Result<(), Error> {
match self.func.take() {
Some((func, rx)) => {
func(rx);
Ok(())
}
None => Err(Error::new(
ErrorKind::Other,
"INTERNAL ERROR: Can't unwrap daemon function",
)),
}
}
fn send(&mut self, state: State) -> Result<(), Error> {
match self.tx {
Some(ref tx) => match tx.send(state) {
Ok(_) => Ok(()),
Err(e) => Err(Error::new(ErrorKind::Other, e)),
},
None => Err(Error::new(ErrorKind::Other, "Service is already exited")),
}
}
fn take_tx(&mut self) -> Option<Sender<State>> {
self.tx.take()
}
}
fn daemon_wrapper<R, F: FnOnce(&mut DaemonHolder) -> R>(func: F) -> R {
let singleton = singleton();
let result = match singleton.lock() {
Ok(ref mut daemon) => func(daemon),
Err(e) => {
panic!("Mutex error: {:?}", e);
}
};
result
}
impl DaemonRunner for Daemon {
fn run<F: 'static + FnOnce(Receiver<State>)>(&self, func: F) -> Result<(), Error> {
let (tx, rx) = channel();
tx.send(State::Start).unwrap();
let mut daemon = DaemonStatic {
holder: Box::new(DaemonFuncHolder {
tx: Some(tx),
func: Some((func, rx)),
}),
};
try!(guard_compare_and_swap(daemon_null(), &mut daemon));
let result = daemon_console(&mut daemon);
try!(guard_compare_and_swap(&mut daemon, daemon_null()));
result
}
}
fn guard_compare_and_swap(
old_value: *mut DaemonStatic,
new_value: *mut DaemonStatic,
) -> Result<(), Error> {
daemon_wrapper(|daemon_static: &mut DaemonHolder| -> Result<(), Error> {
if daemon_static.holder != old_value {
return Err(Error::new(
ErrorKind::Other,
"This function is not reentrant.",
));
}
daemon_static.holder = new_value;
Ok(())
})
}
fn daemon_console(daemon: &mut DaemonStatic) -> Result<(), Error> {
let result;
unsafe {
result = daemon.holder.exec();
}
result
}
unsafe extern "system" fn signal_handler(sig: libc::c_int) {
daemon_wrapper(|daemon_static: &mut DaemonHolder| {
let daemon = &mut *daemon_static.holder;
return match daemon.holder.take_tx() {
Some(ref tx) => {
let _ = tx.send(State::Stop);
}
None => (),
};
});
}
fn daemon_null() -> *mut DaemonStatic {
0 as *mut DaemonStatic
}
extern "C" {
fn raise(sig: libc::c_int) -> libc::c_int;
fn signal(sig: libc::c_int, handler: *const libc::c_void) -> libc::c_int;
fn kill(pid: libc::pid_t, sig: libc::c_int) -> libc::c_int;
}