mirror of
https://git.meli.delivery/meli/meli
synced 2024-10-30 21:20:34 +00:00
Send timer ID as si_value to SIGALRM handler
Associate each alarm signal with the timer of its origin.
This commit is contained in:
parent
a365a846b8
commit
5e912db461
13
Cargo.lock
generated
13
Cargo.lock
generated
@ -746,7 +746,8 @@ dependencies = [
|
||||
"crossbeam 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"melib 0.4.1",
|
||||
"nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"signal-hook 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"signal-hook 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ui 0.4.1",
|
||||
"xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -1523,16 +1524,16 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.1.10"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"signal-hook-registry 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.1.1"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"arc-swap 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2299,8 +2300,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum serde_derive 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)" = "46a3223d0c9ba936b61c0d2e3e559e3217dbfb8d65d06d26e8b3c25de38bae3e"
|
||||
"checksum serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)" = "5a23aa71d4a4d43fdbfaac00eff68ba8a06a51759a89ac3304323e800c4dd40d"
|
||||
"checksum serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97"
|
||||
"checksum signal-hook 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4f61c4d59f3aaa9f61bba6450a9b80ba48362fd7d651689e7a10c453b1f6dc68"
|
||||
"checksum signal-hook-registry 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1797d48f38f91643908bb14e35e79928f9f4b3cefb2420a564dde0991b4358dc"
|
||||
"checksum signal-hook 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "7a9c17dd3ba2d36023a5c9472ecddeda07e27fd0b05436e8c1e0c8f178185652"
|
||||
"checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41"
|
||||
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
||||
"checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6"
|
||||
"checksum smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44e59e0c9fa00817912ae6e4e6e3c4fe04455e75699d06eedc7d85917ed8e8f4"
|
||||
|
@ -11,7 +11,8 @@ path = "src/bin.rs"
|
||||
[dependencies]
|
||||
xdg = "2.1.0"
|
||||
crossbeam = "0.7.2"
|
||||
signal-hook = "0.1.10"
|
||||
signal-hook = "0.1.12"
|
||||
signal-hook-registry = "1.2.0"
|
||||
nix = "*"
|
||||
melib = { path = "melib", version = "*" }
|
||||
ui = { path = "ui", version = "*" }
|
||||
|
30
src/bin.rs
30
src/bin.rs
@ -42,12 +42,23 @@ use ui::*;
|
||||
|
||||
use nix;
|
||||
use std::os::raw::c_int;
|
||||
|
||||
use xdg;
|
||||
|
||||
fn notify(
|
||||
signals: &[c_int],
|
||||
sender: crossbeam::channel::Sender<ThreadEvent>,
|
||||
) -> std::result::Result<crossbeam::channel::Receiver<c_int>, std::io::Error> {
|
||||
let alarm_sender = sender.clone();
|
||||
let alarm_handler = move |info: &nix::libc::siginfo_t| {
|
||||
let value = unsafe { info.si_value().sival_ptr as u8 };
|
||||
alarm_sender
|
||||
.send(ThreadEvent::UIEvent(UIEvent::Timer(value)))
|
||||
.unwrap();
|
||||
};
|
||||
unsafe {
|
||||
signal_hook_registry::register_sigaction(signal_hook::SIGALRM, alarm_handler)?;
|
||||
}
|
||||
let (s, r) = crossbeam::channel::bounded(100);
|
||||
let signals = signal_hook::iterator::Signals::new(signals)?;
|
||||
std::thread::spawn(move || {
|
||||
@ -218,22 +229,21 @@ fn run_app() -> Result<()> {
|
||||
std::env::set_var("MELI_CONFIG", config_location);
|
||||
}
|
||||
|
||||
/* Create the application State. */
|
||||
let mut state = State::new()?;
|
||||
|
||||
let receiver = state.receiver();
|
||||
let sender = state.sender();
|
||||
|
||||
/* Create a channel to communicate with other threads. The main process is the sole receiver.
|
||||
* */
|
||||
let (sender, receiver) = crossbeam::channel::bounded(32 * ::std::mem::size_of::<ThreadEvent>());
|
||||
/* Catch SIGWINCH to handle terminal resizing */
|
||||
let signals = &[
|
||||
signal_hook::SIGALRM,
|
||||
/* Catch SIGWINCH to handle terminal resizing */
|
||||
signal_hook::SIGWINCH,
|
||||
/* Catch SIGCHLD to handle embed applications status change */
|
||||
signal_hook::SIGCHLD,
|
||||
];
|
||||
|
||||
let signal_recvr = notify(signals, sender)?;
|
||||
let signal_recvr = notify(signals, sender.clone())?;
|
||||
|
||||
/* Create the application State. */
|
||||
let mut state = State::new(sender, receiver.clone())?;
|
||||
|
||||
let window = Box::new(Tabbed::new(vec![
|
||||
Box::new(listing::Listing::new(&state.context.accounts)),
|
||||
@ -388,10 +398,6 @@ fn run_app() -> Result<()> {
|
||||
state.redraw();
|
||||
}
|
||||
},
|
||||
signal_hook::SIGALRM => {
|
||||
state.rcv_event(UIEvent::Timer);
|
||||
state.redraw();
|
||||
},
|
||||
other => {
|
||||
debug!("got other signal: {:?}", other);
|
||||
}
|
||||
|
@ -191,9 +191,12 @@ pub mod timer {
|
||||
use libc::sigevent;
|
||||
use libc::{itimerspec, timespec};
|
||||
use nix::sys::signal::{SigEvent, SigevNotify};
|
||||
use std::cell::RefCell;
|
||||
use std::convert::TryInto;
|
||||
use std::time::Duration;
|
||||
|
||||
thread_local!(static TIMER_IDS: RefCell<u8> = RefCell::new(0));
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type timer_t = libc::intptr_t;
|
||||
|
||||
@ -215,6 +218,7 @@ pub mod timer {
|
||||
timer_id: timer_t,
|
||||
interval: Duration,
|
||||
value: Duration,
|
||||
pub si_value: u8,
|
||||
}
|
||||
|
||||
impl Drop for PosixTimer {
|
||||
@ -255,6 +259,35 @@ pub mod timer {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_value(&mut self, value: Duration) {
|
||||
let spec = itimerspec {
|
||||
it_interval: timespec {
|
||||
tv_sec: self.interval.as_secs().try_into().unwrap_or(0),
|
||||
tv_nsec: self.interval.subsec_nanos().try_into().unwrap_or(0),
|
||||
},
|
||||
it_value: timespec {
|
||||
tv_sec: value.as_secs().try_into().unwrap_or(0),
|
||||
tv_nsec: value.subsec_nanos().try_into().unwrap_or(0),
|
||||
},
|
||||
};
|
||||
let ret =
|
||||
unsafe { timer_settime(self.timer_id, 0, &spec as *const _, std::ptr::null_mut()) };
|
||||
if ret != 0 {
|
||||
match ret {
|
||||
libc::EFAULT => {
|
||||
panic!(
|
||||
"EFAULT: new_value, old_value, or curr_value is not a valid pointer."
|
||||
);
|
||||
}
|
||||
libc::EINVAL => {
|
||||
panic!("EINVAL: timerid is invalid.");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
self.value = value;
|
||||
}
|
||||
|
||||
pub fn set_interval(&mut self, interval: Duration) {
|
||||
let spec = itimerspec {
|
||||
it_interval: timespec {
|
||||
@ -320,9 +353,15 @@ pub mod timer {
|
||||
) -> Result<PosixTimer> {
|
||||
let mut timer_id = Default::default();
|
||||
|
||||
let mut si_value = 0;
|
||||
TIMER_IDS.with(|t| {
|
||||
si_value = *t.borrow_mut();
|
||||
*t.borrow_mut() += 1;
|
||||
});
|
||||
|
||||
let sigev_notify = SigevNotify::SigevSignal {
|
||||
signal,
|
||||
si_value: 0,
|
||||
si_value: si_value as isize,
|
||||
};
|
||||
let event = SigEvent::new(sigev_notify);
|
||||
|
||||
@ -382,6 +421,7 @@ pub mod timer {
|
||||
timer_id,
|
||||
interval,
|
||||
value,
|
||||
si_value,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ use super::*;
|
||||
use crate::plugins::PluginManager;
|
||||
use melib::backends::{FolderHash, NotifyFn};
|
||||
|
||||
use crossbeam::channel::{bounded, unbounded, Receiver, Sender};
|
||||
use crossbeam::channel::{unbounded, Receiver, Sender};
|
||||
use fnv::FnvHashMap;
|
||||
use std::env;
|
||||
use std::io::Write;
|
||||
@ -199,11 +199,7 @@ impl Drop for State {
|
||||
}
|
||||
|
||||
impl State {
|
||||
pub fn new() -> Result<Self> {
|
||||
/* Create a channel to communicate with other threads. The main process is the sole receiver.
|
||||
* */
|
||||
let (sender, receiver) = bounded(32 * ::std::mem::size_of::<ThreadEvent>());
|
||||
|
||||
pub fn new(sender: Sender<ThreadEvent>, receiver: Receiver<ThreadEvent>) -> Result<Self> {
|
||||
/*
|
||||
* Create async channel to block the input-thread if we need to fork and stop it from reading
|
||||
* stdin, see get_events() for details
|
||||
|
@ -106,6 +106,7 @@ pub enum UIEvent {
|
||||
EnvelopeUpdate(EnvelopeHash),
|
||||
EnvelopeRename(EnvelopeHash, EnvelopeHash), // old_hash, new_hash
|
||||
EnvelopeRemove(EnvelopeHash),
|
||||
Timer(u8),
|
||||
}
|
||||
|
||||
impl From<RefreshEvent> for UIEvent {
|
||||
|
Loading…
Reference in New Issue
Block a user