Skip to content

Commit

Permalink
add signal handling and cleanup logic on terms signals
Browse files Browse the repository at this point in the history
  • Loading branch information
doums committed Aug 29, 2024
1 parent a1bf7ae commit 084663d
Show file tree
Hide file tree
Showing 21 changed files with 266 additions and 62 deletions.
22 changes: 21 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "baru"
version = "0.4.1"
version = "0.4.2"
description = "A simple system monitor for WM statusbar"
authors = ["pierre <dommerc.pierre@gmail.com>"]
edition = "2021"
Expand All @@ -22,6 +22,7 @@ once_cell = "1.19.0"
chrono = "0.4"
regex = "1"
reqwest = { version = "0.12.6", features = ["blocking", "json"] }
signal-hook = "0.3.17"

[build-dependencies]
cmake = "0.1"
Expand Down
5 changes: 2 additions & 3 deletions lib/audio/include/audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@
*/
#define VOLUME(N) (uint32_t)(((uint64_t)N * 100 + (uint64_t)PA_VOLUME_NORM / 2) / (uint64_t)PA_VOLUME_NORM)

static bool alive = true;

typedef struct timespec
t_timespec;

Expand Down Expand Up @@ -62,7 +60,8 @@ typedef struct main {
t_data *source;
} t_main;

void run(uint32_t tick,
void run(bool *running,
uint32_t tick,
const char *sink_name,
const char *source_name,
void *cb_context,
Expand Down
6 changes: 3 additions & 3 deletions lib/audio/src/audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ void iterate(t_main *main) {
clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &tick, NULL);
}

void run(uint32_t tick, const char *sink_name, const char *source_name, void *cb_context, send_cb sink_cb,
send_cb source_cb) {
void run(bool *running, uint32_t tick, const char *sink_name, const char *source_name, void *cb_context,
send_cb sink_cb, send_cb source_cb) {
pa_proplist *proplist;
t_main main;
t_data sink;
Expand Down Expand Up @@ -223,7 +223,7 @@ void run(uint32_t tick, const char *sink_name, const char *source_name, void *cb
pa_context_set_subscribe_callback(main.context, subscription_cb, &main);

// iterate main loop
while (alive) {
while (*running == true) {
iterate(&main);
}

Expand Down
25 changes: 23 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ mod module;
mod modules;
mod netlink;
mod pulse;
pub mod signal;
pub mod trace;
pub mod util;

Expand All @@ -27,11 +28,17 @@ use modules::temperature::Config as TemperatureConfig;
use modules::weather::Config as WeatherConfig;
use modules::wired::Config as WiredConfig;
use modules::wireless::Config as WirelessConfig;
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
use std::sync::atomic::AtomicBool;
use std::sync::mpsc::{self, Receiver, Sender};
use std::thread;
use std::thread::JoinHandle;
use tracing::{error, info, instrument};

// Global application state, used to terminate the main-loop and all modules
pub static RUN: Lazy<AtomicBool> = Lazy::new(|| AtomicBool::new(true));

#[derive(Debug)]
/// Message sent by modules.
/// `0`: module key,
Expand Down Expand Up @@ -65,6 +72,7 @@ pub struct Baru<'a> {
format: &'a str,
markup_matches: Vec<MarkupMatch>,
channel: (Sender<ModuleMsg>, Receiver<ModuleMsg>),
pulse: Option<JoinHandle<Result<(), Error>>>,
}

#[derive(Debug)]
Expand All @@ -84,6 +92,7 @@ impl<'a> Baru<'a> {
modules,
format: &config.format,
markup_matches,
pulse: None,
})
}

Expand All @@ -92,7 +101,7 @@ impl<'a> Baru<'a> {
// check if any module needs pulse, i.e. sound or mic modules
let need_pulse = self.modules.iter().any(|m| m.key == 's' || m.key == 'i');
if need_pulse {
pulse::init(self.config);
self.pulse = Some(pulse::init(self.config)?);
}
for data in &mut self.modules {
let builder = thread::Builder::new().name(format!("mod_{}", data.module.name()));
Expand All @@ -102,8 +111,9 @@ impl<'a> Baru<'a> {
let key = data.key;
let c_name = data.module.name().to_string();
let handle = builder.spawn(move || -> Result<(), Error> {
run(key, cloned_m_conf, tx1)
run(&RUN, key, cloned_m_conf, tx1)
.inspect_err(|e| error!("[{}] module failed: {}", c_name, e))?;
info!("[{}] module stopped", c_name);
Ok(())
})?;
data.start(handle);
Expand Down Expand Up @@ -146,6 +156,17 @@ impl<'a> Baru<'a> {
pub fn modules(&self) -> Vec<&str> {
self.modules.iter().map(|m| m.module.name()).collect()
}

#[instrument(skip_all)]
pub fn cleanup(&mut self) {
if let Some(pulse) = self.pulse.take() {
match pulse.join() {
Ok(Ok(_)) => info!("pulse module terminated"),
Ok(Err(e)) => error!("pulse module failed: {}", e),
Err(_) => error!("pulse module panicked"),
};
}
}
}

#[instrument]
Expand Down
11 changes: 9 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@

use anyhow::{Context, Result};
use baru::cli::Cli;
use baru::{trace, util, Baru, Config};
use baru::{signal, trace, util, Baru, Config, RUN};
use clap::Parser;
use std::env;
use std::fs;
use std::path::{Path, PathBuf};
use std::sync::atomic::Ordering;
use std::thread;
use std::time::{Duration, Instant};
use tracing::{debug, error, info};
Expand All @@ -22,6 +23,8 @@ fn main() -> Result<()> {
let cli = Cli::parse();
let _g = trace::init(cli.logs).context("failed to init tracing")?;

signal::catch_signals()?;

let home = env::var("HOME")?;
let mut config_dir = env::var(XDG_CONFIG_HOME)
.map(PathBuf::from)
Expand Down Expand Up @@ -56,7 +59,7 @@ fn main() -> Result<()> {
let mut iteration_end: Duration;

info!("launching main loop");
loop {
while RUN.load(Ordering::Relaxed) {
iteration_start = Instant::now();
baru.update()
.inspect_err(|e| error!("failed to update: {}", e))?;
Expand All @@ -65,4 +68,8 @@ fn main() -> Result<()> {
thread::sleep(tick - iteration_end);
}
}

baru.cleanup();
info!("exiting");
Ok(())
}
14 changes: 13 additions & 1 deletion src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,14 @@ use crate::ModuleMsg;

use anyhow::{anyhow, Result};
use std::convert::TryFrom;
use std::sync::atomic::AtomicBool;
use std::sync::mpsc::Sender;
use std::thread::JoinHandle;
use tracing::{error, info, instrument};

const MODULE_FAILED_ICON: &str = "✗";

pub type RunPtr = fn(char, Config, Sender<ModuleMsg>) -> Result<(), Error>;
pub type RunPtr = fn(&AtomicBool, char, Config, Sender<ModuleMsg>) -> Result<(), Error>;

pub trait Bar {
fn name(&self) -> &str;
Expand Down Expand Up @@ -241,4 +242,15 @@ impl<'a> ModuleData<'a> {
};
Ok(())
}

#[instrument(skip_all)]
pub fn _terminate(&mut self) {
if let Some(handle) = self.handle.take() {
match handle.join() {
Ok(Ok(_)) => info!("[{}] module terminated", self.module.name()),
Ok(Err(e)) => error!("[{}] module failed: {}", self.module.name(), e),
Err(_) => error!("[{}] module panicked", self.module.name()),
};
}
}
}
11 changes: 9 additions & 2 deletions src/modules/battery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use serde::{Deserialize, Serialize};
use std::convert::TryFrom;
use std::fs::{self, File};
use std::io::{self, prelude::*, BufReader};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::Sender;
use std::thread;
use std::time::{Duration, Instant};
Expand Down Expand Up @@ -173,12 +174,17 @@ impl<'a> Bar for Battery<'a> {
}

#[instrument(skip_all)]
pub fn run(key: char, main_config: MainConfig, tx: Sender<ModuleMsg>) -> Result<(), Error> {
pub fn run(
running: &AtomicBool,
key: char,
main_config: MainConfig,
tx: Sender<ModuleMsg>,
) -> Result<(), Error> {
let config = InternalConfig::try_from(&main_config)?;
debug!("{:#?}", config);
let mut iteration_start: Instant;
let mut iteration_end: Duration;
loop {
while running.load(Ordering::Relaxed) {
iteration_start = Instant::now();
let (energy, capacity, status) = parse_attributes(
&config.uevent,
Expand Down Expand Up @@ -210,6 +216,7 @@ pub fn run(key: char, main_config: MainConfig, tx: Sender<ModuleMsg>) -> Result<
thread::sleep(config.tick - iteration_end);
}
}
Ok(())
}

fn parse_attributes(
Expand Down
11 changes: 9 additions & 2 deletions src/modules/brightness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::module::{Bar, RunPtr};
use crate::util::read_and_parse;
use crate::{Config as MainConfig, ModuleMsg};
use serde::{Deserialize, Serialize};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::Sender;
use std::thread;
use std::time::{Duration, Instant};
Expand Down Expand Up @@ -102,12 +103,17 @@ impl<'a> Bar for Brightness<'a> {
}

#[instrument(skip_all)]
pub fn run(key: char, main_config: MainConfig, tx: Sender<ModuleMsg>) -> Result<(), Error> {
pub fn run(
running: &AtomicBool,
key: char,
main_config: MainConfig,
tx: Sender<ModuleMsg>,
) -> Result<(), Error> {
let config = InternalConfig::from(&main_config);
debug!("{:#?}", config);
let mut iteration_start: Instant;
let mut iteration_end: Duration;
loop {
while running.load(Ordering::Relaxed) {
iteration_start = Instant::now();
let brightness = read_and_parse(&format!("{}/actual_brightness", config.sys_path))?;
let max_brightness = read_and_parse(&format!("{}/max_brightness", config.sys_path))?;
Expand All @@ -122,4 +128,5 @@ pub fn run(key: char, main_config: MainConfig, tx: Sender<ModuleMsg>) -> Result<
thread::sleep(config.tick - iteration_end);
}
}
Ok(())
}
11 changes: 9 additions & 2 deletions src/modules/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use serde::{Deserialize, Serialize};
use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::Sender;
use std::thread;
use std::time::{Duration, Instant};
Expand Down Expand Up @@ -115,14 +116,19 @@ impl<'a> Bar for Cpu<'a> {
}

#[instrument(skip_all)]
pub fn run(key: char, main_config: MainConfig, tx: Sender<ModuleMsg>) -> Result<(), Error> {
pub fn run(
running: &AtomicBool,
key: char,
main_config: MainConfig,
tx: Sender<ModuleMsg>,
) -> Result<(), Error> {
let config = InternalConfig::from(&main_config);
debug!("{:#?}", config);
let mut prev_idle = 0;
let mut prev_total = 0;
let mut iteration_start: Instant;
let mut iteration_end: Duration;
loop {
while running.load(Ordering::Relaxed) {
iteration_start = Instant::now();
let proc_stat = File::open(config.proc_stat)?;
let mut reader = BufReader::new(proc_stat);
Expand Down Expand Up @@ -158,4 +164,5 @@ pub fn run(key: char, main_config: MainConfig, tx: Sender<ModuleMsg>) -> Result<
thread::sleep(config.tick - iteration_end);
}
}
Ok(())
}
11 changes: 9 additions & 2 deletions src/modules/cpu_freq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::util::read_and_parse;
use crate::{Config as MainConfig, ModuleMsg};
use serde::{Deserialize, Serialize};
use std::fs::{read_dir, DirEntry};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::Sender;
use std::thread;
use std::time::{Duration, Instant};
Expand Down Expand Up @@ -177,12 +178,17 @@ impl<'a> Bar for CpuFreq<'a> {
}

#[instrument(skip_all)]
pub fn run(key: char, main_config: MainConfig, tx: Sender<ModuleMsg>) -> Result<(), Error> {
pub fn run(
running: &AtomicBool,
key: char,
main_config: MainConfig,
tx: Sender<ModuleMsg>,
) -> Result<(), Error> {
let config = InternalConfig::try_from(&main_config)?;
debug!("{:#?}", config);
let mut iteration_start: Instant;
let mut iteration_end: Duration;
loop {
while running.load(Ordering::Relaxed) {
iteration_start = Instant::now();
let freqs: Vec<f32> = read_dir(Path::new(SYSFS_CPUFREQ))?
.filter_map(|entry| entry.ok())
Expand Down Expand Up @@ -216,6 +222,7 @@ pub fn run(key: char, main_config: MainConfig, tx: Sender<ModuleMsg>) -> Result<
thread::sleep(config.tick - iteration_end);
}
}
Ok(())
}

fn humanize(average: f32, unit: Unit) -> String {
Expand Down
Loading

0 comments on commit 084663d

Please sign in to comment.