watcher: Allow running a processing function on the thread

This commit is contained in:
Ivan Molodetskikh
2025-02-12 20:53:19 +03:00
parent 7e552333a9
commit eb8bd3894a
2 changed files with 16 additions and 8 deletions
+1 -1
View File
@@ -231,7 +231,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// Set up config file watcher. // Set up config file watcher.
let _watcher = { let _watcher = {
let (tx, rx) = calloop::channel::sync_channel(1); let (tx, rx) = calloop::channel::sync_channel(1);
let watcher = Watcher::new(watch_path.clone(), tx); let watcher = Watcher::new(watch_path.clone(), |_| (), tx);
event_loop event_loop
.handle() .handle()
.insert_source(rx, move |event, _, state| match event { .insert_source(rx, move |event, _, state| match event {
+15 -7
View File
@@ -1,6 +1,6 @@
//! File modification watcher. //! File modification watcher.
use std::path::PathBuf; use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{mpsc, Arc}; use std::sync::{mpsc, Arc};
use std::thread; use std::thread;
@@ -19,13 +19,18 @@ impl Drop for Watcher {
} }
impl Watcher { impl Watcher {
pub fn new(path: PathBuf, changed: SyncSender<()>) -> Self { pub fn new<T: Send + 'static>(
Self::with_start_notification(path, changed, None) path: PathBuf,
process: impl FnMut(&Path) -> T + Send + 'static,
changed: SyncSender<T>,
) -> Self {
Self::with_start_notification(path, process, changed, None)
} }
pub fn with_start_notification( pub fn with_start_notification<T: Send + 'static>(
path: PathBuf, path: PathBuf,
changed: SyncSender<()>, mut process: impl FnMut(&Path) -> T + Send + 'static,
changed: SyncSender<T>,
started: Option<mpsc::SyncSender<()>>, started: Option<mpsc::SyncSender<()>>,
) -> Self { ) -> Self {
let should_stop = Arc::new(AtomicBool::new(false)); let should_stop = Arc::new(AtomicBool::new(false));
@@ -66,7 +71,9 @@ impl Watcher {
if last_props.as_ref() != Some(&new_props) { if last_props.as_ref() != Some(&new_props) {
trace!("file changed: {}", path.to_string_lossy()); trace!("file changed: {}", path.to_string_lossy());
if let Err(err) = changed.send(()) { let rv = process(&path);
if let Err(err) = changed.send(rv) {
warn!("error sending change notification: {err:?}"); warn!("error sending change notification: {err:?}");
break; break;
} }
@@ -123,7 +130,8 @@ mod tests {
let (tx, rx) = sync_channel(1); let (tx, rx) = sync_channel(1);
let (started_tx, started_rx) = mpsc::sync_channel(1); let (started_tx, started_rx) = mpsc::sync_channel(1);
let _watcher = Watcher::with_start_notification(config_path.clone(), tx, Some(started_tx)); let _watcher =
Watcher::with_start_notification(config_path.clone(), |_| (), tx, Some(started_tx));
loop_handle loop_handle
.insert_source(rx, |_, _, _| { .insert_source(rx, |_, _, _| {
changed.fetch_add(1, Ordering::SeqCst); changed.fetch_add(1, Ordering::SeqCst);