mirror of
https://git.meli.delivery/meli/meli
synced 2024-10-30 21:20:34 +00:00
bin: use self-pipe in signal handler
send_timeout() isn't signal safe, and might block.
This commit is contained in:
parent
7990b71c19
commit
1717aa7845
34
src/bin.rs
34
src/bin.rs
@ -98,31 +98,47 @@ fn notify(
|
|||||||
sender: crossbeam::channel::Sender<ThreadEvent>,
|
sender: crossbeam::channel::Sender<ThreadEvent>,
|
||||||
) -> std::result::Result<crossbeam::channel::Receiver<c_int>, std::io::Error> {
|
) -> std::result::Result<crossbeam::channel::Receiver<c_int>, std::io::Error> {
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
let alarm_sender = sender.clone();
|
let (alarm_pipe_r, alarm_pipe_w) = nix::unistd::pipe().map_err(|err| {
|
||||||
|
std::io::Error::from_raw_os_error(err.as_errno().map(|n| n as i32).unwrap_or(0))
|
||||||
|
})?;
|
||||||
let alarm_handler = move |info: &nix::libc::siginfo_t| {
|
let alarm_handler = move |info: &nix::libc::siginfo_t| {
|
||||||
let value = unsafe { info.si_value().sival_ptr as u8 };
|
let value = unsafe { info.si_value().sival_ptr as u8 };
|
||||||
alarm_sender
|
let _ = nix::unistd::write(alarm_pipe_w, &[value]);
|
||||||
.send_timeout(
|
|
||||||
ThreadEvent::UIEvent(UIEvent::Timer(value)),
|
|
||||||
Duration::from_millis(500),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
};
|
};
|
||||||
unsafe {
|
unsafe {
|
||||||
signal_hook_registry::register_sigaction(signal_hook::SIGALRM, alarm_handler)?;
|
signal_hook_registry::register_sigaction(signal_hook::SIGALRM, alarm_handler)?;
|
||||||
}
|
}
|
||||||
let (s, r) = crossbeam::channel::bounded(100);
|
let (s, r) = crossbeam::channel::bounded(100);
|
||||||
let signals = signal_hook::iterator::Signals::new(signals)?;
|
let signals = signal_hook::iterator::Signals::new(signals)?;
|
||||||
|
let _ = nix::fcntl::fcntl(
|
||||||
|
alarm_pipe_r,
|
||||||
|
nix::fcntl::FcntlArg::F_SETFL(nix::fcntl::OFlag::O_NONBLOCK),
|
||||||
|
);
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
|
let mut buf = [0; 1];
|
||||||
let mut ctr = 0;
|
let mut ctr = 0;
|
||||||
loop {
|
loop {
|
||||||
ctr %= 3;
|
ctr %= 3;
|
||||||
if ctr == 0 {
|
if ctr == 0 {
|
||||||
sender.send_timeout(ThreadEvent::Pulse, Duration::from_millis(500));
|
let _ = sender
|
||||||
|
.send_timeout(ThreadEvent::Pulse, Duration::from_millis(500))
|
||||||
|
.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
for signal in signals.pending() {
|
for signal in signals.pending() {
|
||||||
s.send_timeout(signal, Duration::from_millis(500)).unwrap();
|
let _ = s.send_timeout(signal, Duration::from_millis(500)).ok();
|
||||||
|
}
|
||||||
|
while nix::unistd::read(alarm_pipe_r, buf.as_mut())
|
||||||
|
.map(|s| s > 0)
|
||||||
|
.unwrap_or(false)
|
||||||
|
{
|
||||||
|
let value = buf[0];
|
||||||
|
sender
|
||||||
|
.send_timeout(
|
||||||
|
ThreadEvent::UIEvent(UIEvent::Timer(value)),
|
||||||
|
Duration::from_millis(500),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::thread::sleep(std::time::Duration::from_millis(100));
|
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||||
|
Loading…
Reference in New Issue
Block a user