diff --git a/notify/src/fsevent.rs b/notify/src/fsevent.rs index c52ae391..b7fde513 100644 --- a/notify/src/fsevent.rs +++ b/notify/src/fsevent.rs @@ -585,7 +585,7 @@ fn test_fsevent_watcher_drop() { let (tx, rx) = std::sync::mpsc::channel(); { - let mut watcher = FsEventWatcher::new(tx).unwrap(); + let mut watcher = FsEventWatcher::new(tx, Default::default()).unwrap(); watcher.watch(dir.path(), RecursiveMode::Recursive).unwrap(); thread::sleep(Duration::from_millis(2000)); println!("is running -> {}", watcher.is_running()); diff --git a/notify/src/kqueue.rs b/notify/src/kqueue.rs index 61858c0a..571221b8 100644 --- a/notify/src/kqueue.rs +++ b/notify/src/kqueue.rs @@ -5,7 +5,7 @@ //! pieces of kernel code termed filters. use super::event::*; -use super::{Error, EventHandler, RecursiveMode, Result, Watcher, Config}; +use super::{Config, Error, EventHandler, RecursiveMode, Result, Watcher}; use crate::{unbounded, Receiver, Sender}; use kqueue::{EventData, EventFilter, FilterFlag, Ident}; use std::collections::HashMap; @@ -288,18 +288,23 @@ impl EventLoop { // If the watch is not recursive, or if we determine (by stat'ing the path to get its // metadata) that the watched path is not a directory, add a single path watch. if !is_recursive || !metadata(&path).map_err(Error::io)?.is_dir() { - return self.add_single_watch(path, false); + self.add_single_watch(path, false)?; + } else { + for entry in WalkDir::new(path).follow_links(true).into_iter() { + let entry = entry.map_err(map_walkdir_error)?; + self.add_single_watch(entry.path().to_path_buf(), is_recursive)?; + } } - for entry in WalkDir::new(path).follow_links(true).into_iter() { - let entry = entry.map_err(map_walkdir_error)?; - self.add_single_watch(entry.path().to_path_buf(), is_recursive)?; - } + // Only make a single `kevent` syscall to add all the watches. self.kqueue.watch()?; Ok(()) } + /// Adds a single watch to the kqueue. + /// + /// The caller of this function must call `self.kqueue.watch()` afterwards to register the new watch. fn add_single_watch(&mut self, path: PathBuf, is_recursive: bool) -> Result<()> { let event_filter = EventFilter::EVFILT_VNODE; let filter_flags = FilterFlag::NOTE_DELETE @@ -314,7 +319,7 @@ impl EventLoop { .add_filename(&path, event_filter, filter_flags) .map_err(|e| Error::io(e).add_path(path.clone()))?; self.watches.insert(path, is_recursive); - self.kqueue.watch()?; + Ok(()) }