Skip to content

Commit 43633b5

Browse files
committed
Add filtered watch implementation for kqueue.
1 parent cee15b4 commit 43633b5

File tree

1 file changed

+33
-9
lines changed

1 file changed

+33
-9
lines changed

notify/src/kqueue.rs

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ struct EventLoop {
3333
event_loop_rx: Receiver<EventLoopMsg>,
3434
kqueue: kqueue::Watcher,
3535
event_handler: Box<dyn EventHandler>,
36-
watches: HashMap<PathBuf, bool>,
36+
watches: HashMap<PathBuf, (bool, WatchFilter)>,
3737
follow_symlinks: bool,
3838
}
3939

@@ -45,7 +45,7 @@ pub struct KqueueWatcher {
4545
}
4646

4747
enum EventLoopMsg {
48-
AddWatch(PathBuf, RecursiveMode, Sender<Result<()>>),
48+
AddWatch(PathBuf, RecursiveMode, WatchFilter, Sender<Result<()>>),
4949
RemoveWatch(PathBuf, Sender<Result<()>>),
5050
Shutdown,
5151
}
@@ -130,8 +130,9 @@ impl EventLoop {
130130
fn handle_messages(&mut self) {
131131
while let Ok(msg) = self.event_loop_rx.try_recv() {
132132
match msg {
133-
EventLoopMsg::AddWatch(path, recursive_mode, tx) => {
134-
let _ = tx.send(self.add_watch(path, recursive_mode.is_recursive()));
133+
EventLoopMsg::AddWatch(path, recursive_mode, watch_filter, tx) => {
134+
let _ =
135+
tx.send(self.add_watch(path, recursive_mode.is_recursive(), watch_filter));
135136
}
136137
EventLoopMsg::RemoveWatch(path, tx) => {
137138
let _ = tx.send(self.remove_watch(path, false));
@@ -288,11 +289,20 @@ impl EventLoop {
288289
}
289290

290291
for path in add_watches {
291-
self.add_watch(path, true).ok();
292+
self.add_watch(path, true, WatchFilter::accept_all()).ok();
292293
}
293294
}
294295

295-
fn add_watch(&mut self, path: PathBuf, is_recursive: bool) -> Result<()> {
296+
fn add_watch(
297+
&mut self,
298+
path: PathBuf,
299+
is_recursive: bool,
300+
watch_filter: WatchFilter,
301+
) -> Result<()> {
302+
if !watch_filter.should_watch(&path) {
303+
return Ok(());
304+
}
305+
296306
// If the watch is not recursive, or if we determine (by stat'ing the path to get its
297307
// metadata) that the watched path is not a directory, add a single path watch.
298308
if !is_recursive || !metadata(&path).map_err(Error::io)?.is_dir() {
@@ -387,15 +397,20 @@ impl KqueueWatcher {
387397
Ok(KqueueWatcher { channel, waker })
388398
}
389399

390-
fn watch_inner(&mut self, path: &Path, recursive_mode: RecursiveMode) -> Result<()> {
400+
fn watch_inner(
401+
&mut self,
402+
path: &Path,
403+
recursive_mode: RecursiveMode,
404+
watch_filter: WatchFilter,
405+
) -> Result<()> {
391406
let pb = if path.is_absolute() {
392407
path.to_owned()
393408
} else {
394409
let p = env::current_dir().map_err(Error::io)?;
395410
p.join(path)
396411
};
397412
let (tx, rx) = unbounded();
398-
let msg = EventLoopMsg::AddWatch(pb, recursive_mode, tx);
413+
let msg = EventLoopMsg::AddWatch(pb, recursive_mode, watch_filter, tx);
399414

400415
self.channel
401416
.send(msg)
@@ -436,8 +451,17 @@ impl Watcher for KqueueWatcher {
436451
Self::from_event_handler(Box::new(event_handler), config.follow_symlinks())
437452
}
438453

454+
fn watch_filtered(
455+
&mut self,
456+
path: &Path,
457+
recursive_mode: RecursiveMode,
458+
watch_filter: WatchFilter,
459+
) -> Result<()> {
460+
self.watch_inner(path, recursive_mode, watch_filter)
461+
}
462+
439463
fn watch(&mut self, path: &Path, recursive_mode: RecursiveMode) -> Result<()> {
440-
self.watch_inner(path, recursive_mode)
464+
self.watch_inner(path, recursive_mode, WatchFilter::accept_all())
441465
}
442466

443467
fn unwatch(&mut self, path: &Path) -> Result<()> {

0 commit comments

Comments
 (0)