aboutsummaryrefslogtreecommitdiff
path: root/alacritty/src/config/monitor.rs
diff options
context:
space:
mode:
Diffstat (limited to 'alacritty/src/config/monitor.rs')
-rw-r--r--alacritty/src/config/monitor.rs37
1 files changed, 36 insertions, 1 deletions
diff --git a/alacritty/src/config/monitor.rs b/alacritty/src/config/monitor.rs
index 53cff1c9..3f73f120 100644
--- a/alacritty/src/config/monitor.rs
+++ b/alacritty/src/config/monitor.rs
@@ -1,3 +1,5 @@
+use std::collections::hash_map::DefaultHasher;
+use std::hash::{Hash, Hasher};
use std::path::PathBuf;
use std::sync::mpsc::{self, RecvTimeoutError, Sender};
use std::thread::JoinHandle;
@@ -23,6 +25,7 @@ const FALLBACK_POLLING_TIMEOUT: Duration = Duration::from_secs(1);
pub struct ConfigMonitor {
thread: JoinHandle<()>,
shutdown_tx: Sender<Result<NotifyEvent, NotifyError>>,
+ watched_hash: Option<u64>,
}
impl ConfigMonitor {
@@ -32,6 +35,9 @@ impl ConfigMonitor {
return None;
}
+ // Calculate the hash for the unmodified list of paths.
+ let watched_hash = Self::hash_paths(&paths);
+
// Exclude char devices like `/dev/null`, sockets, and so on, by checking that file type is
// a regular file.
paths.retain(|path| {
@@ -139,7 +145,7 @@ impl ConfigMonitor {
}
});
- Some(Self { thread: join_handle, shutdown_tx: tx })
+ Some(Self { watched_hash, thread: join_handle, shutdown_tx: tx })
}
/// Synchronously shut down the monitor.
@@ -154,4 +160,33 @@ impl ConfigMonitor {
warn!("config monitor shutdown failed: {err:?}");
}
}
+
+ /// Check if the config monitor needs to be restarted.
+ ///
+ /// This checks the supplied list of files against the monitored files to determine if a
+ /// restart is necessary.
+ pub fn needs_restart(&self, files: &[PathBuf]) -> bool {
+ Self::hash_paths(files).map_or(true, |hash| Some(hash) == self.watched_hash)
+ }
+
+ /// Generate the hash for a list of paths.
+ fn hash_paths(files: &[PathBuf]) -> Option<u64> {
+ // Use file count limit to avoid allocations.
+ const MAX_PATHS: usize = 1024;
+ if files.len() > MAX_PATHS {
+ return None;
+ }
+
+ // Sort files to avoid restart on order change.
+ let mut sorted_files = [None; MAX_PATHS];
+ for (i, file) in files.iter().enumerate() {
+ sorted_files[i] = Some(file);
+ }
+ sorted_files.sort_unstable();
+
+ // Calculate hash for the paths, regardless of order.
+ let mut hasher = DefaultHasher::new();
+ Hash::hash_slice(&sorted_files, &mut hasher);
+ Some(hasher.finish())
+ }
}