summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock13
-rw-r--r--Cargo.toml3
-rw-r--r--src/bin.rs30
-rw-r--r--ui/src/lib.rs42
-rw-r--r--ui/src/state.rs8
-rw-r--r--ui/src/types.rs1
6 files changed, 71 insertions, 26 deletions
diff --git a/Cargo.lock b/Cargo.lock
index f67bb3b1..1f4843e1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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"
diff --git a/Cargo.toml b/Cargo.toml
index f45e1fec..29108971 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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 = "*" }
diff --git a/src/bin.rs b/src/bin.rs
index d031c92a..953b03ff 100644
--- a/src/bin.rs
+++ b/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);
}
diff --git a/ui/src/lib.rs b/ui/src/lib.rs
index 3fbc37c8..98d23ed6 100644
--- a/ui/src/lib.rs
+++ b/ui/src/lib.rs
@@ -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,
})
}
}
diff --git a/ui/src/state.rs b/ui/src/state.rs
index 360f08eb..1067f2e0 100644
--- a/ui/src/state.rs
+++ b/ui/src/state.rs
@@ -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
diff --git a/ui/src/types.rs b/ui/src/types.rs
index 166b17e1..e8c76ec6 100644
--- a/ui/src/types.rs
+++ b/ui/src/types.rs
@@ -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 {