From 0d1898ad881e05abf93c73fc8a13e4e5e5596335 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Fri, 1 May 2020 22:12:00 +0200 Subject: only cancel current search on Ctrl-C This is not yet perfect, as it seems to still execute all queued threads just to immediately exit them, so maybe we should try and see if we can "clear" the rayon queue. But it's a good start, and the ctrlc crate seems to work well for this job. --- src/main.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index cb67968..61c332e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ use std::fs::File; use std::io::{BufReader, Read, Seek}; use std::path::PathBuf; use std::str::FromStr; +use std::sync::atomic::{AtomicBool, Ordering}; use anyhow::{anyhow, Error, Result}; use chrono::{DateTime, TimeZone, Utc}; @@ -220,6 +221,10 @@ impl fmt::Display for InputError { impl std::error::Error for InputError {} +/// A flag that indicates whether the current search should be interrupted because the user pressed +/// Crtl-C. +static INTERRUPTED: AtomicBool = AtomicBool::new(false); + fn main() { let result = run(); if let Err(err) = result { @@ -290,11 +295,15 @@ fn single(opt: &Opt) -> Result<()> { } fn repl(opt: &Opt) -> Result<()> { + ctrlc::set_handler(|| INTERRUPTED.store(true, Ordering::Relaxed)) + .expect("Could not set interrupt hanlder"); + let mut rl = Editor::<()>::new(); loop { let line = rl.readline("Query> ")?; rl.add_history_entry(&line); let parsed = build_filter(&line); + INTERRUPTED.store(false, Ordering::Relaxed); match parsed { Ok(filter) => grep(&opt, &*filter)?, Err(err) => display_error(&err), @@ -333,6 +342,10 @@ fn grep(opt: &Opt, filter: &dyn LogFilter) -> Result<()> { for entry in walker { let entry = entry?; s.spawn(move |_| { + // Check first if we should even still continue + if INTERRUPTED.load(Ordering::Relaxed) { + return; + } if is_log_file(&entry) { let search = search_log(&entry, filter); match search { -- cgit v1.2.3