aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/vfs-notify/src/lib.rs43
1 files changed, 14 insertions, 29 deletions
diff --git a/crates/vfs-notify/src/lib.rs b/crates/vfs-notify/src/lib.rs
index b1ea298ae..ee5035554 100644
--- a/crates/vfs-notify/src/lib.rs
+++ b/crates/vfs-notify/src/lib.rs
@@ -10,10 +10,9 @@ mod include;
10 10
11use std::convert::{TryFrom, TryInto}; 11use std::convert::{TryFrom, TryInto};
12 12
13use crossbeam_channel::{select, unbounded, Receiver, Sender}; 13use crossbeam_channel::{never, select, unbounded, Receiver, Sender};
14use notify::{RecommendedWatcher, RecursiveMode, Watcher}; 14use notify::{RecommendedWatcher, RecursiveMode, Watcher};
15use paths::{AbsPath, AbsPathBuf}; 15use paths::{AbsPath, AbsPathBuf};
16use rustc_hash::FxHashSet;
17use vfs::loader; 16use vfs::loader;
18use walkdir::WalkDir; 17use walkdir::WalkDir;
19 18
@@ -55,10 +54,8 @@ type NotifyEvent = notify::Result<notify::Event>;
55struct NotifyActor { 54struct NotifyActor {
56 sender: loader::Sender, 55 sender: loader::Sender,
57 config: Vec<(AbsPathBuf, Include, bool)>, 56 config: Vec<(AbsPathBuf, Include, bool)>,
58 watched_paths: FxHashSet<AbsPathBuf>, 57 // Drop order is significant.
59 // Drop order of fields bellow is significant, 58 watcher: Option<(RecommendedWatcher, Receiver<NotifyEvent>)>,
60 watcher: Option<RecommendedWatcher>,
61 watcher_receiver: Receiver<NotifyEvent>,
62} 59}
63 60
64#[derive(Debug)] 61#[derive(Debug)]
@@ -69,23 +66,13 @@ enum Event {
69 66
70impl NotifyActor { 67impl NotifyActor {
71 fn new(sender: loader::Sender) -> NotifyActor { 68 fn new(sender: loader::Sender) -> NotifyActor {
72 let (watcher_sender, watcher_receiver) = unbounded(); 69 NotifyActor { sender, config: Vec::new(), watcher: None }
73 let watcher = log_notify_error(Watcher::new_immediate(move |event| {
74 watcher_sender.send(event).unwrap()
75 }));
76
77 NotifyActor {
78 sender,
79 config: Vec::new(),
80 watched_paths: FxHashSet::default(),
81 watcher,
82 watcher_receiver,
83 }
84 } 70 }
85 fn next_event(&self, receiver: &Receiver<Message>) -> Option<Event> { 71 fn next_event(&self, receiver: &Receiver<Message>) -> Option<Event> {
72 let watcher_receiver = self.watcher.as_ref().map(|(_, receiver)| receiver);
86 select! { 73 select! {
87 recv(receiver) -> it => it.ok().map(Event::Message), 74 recv(receiver) -> it => it.ok().map(Event::Message),
88 recv(&self.watcher_receiver) -> it => Some(Event::NotifyEvent(it.unwrap())), 75 recv(watcher_receiver.unwrap_or(&never())) -> it => Some(Event::NotifyEvent(it.unwrap())),
89 } 76 }
90 } 77 }
91 fn run(mut self, inbox: Receiver<Message>) { 78 fn run(mut self, inbox: Receiver<Message>) {
@@ -94,10 +81,16 @@ impl NotifyActor {
94 match event { 81 match event {
95 Event::Message(msg) => match msg { 82 Event::Message(msg) => match msg {
96 Message::Config(config) => { 83 Message::Config(config) => {
84 self.watcher = None;
85 let (watcher_sender, watcher_receiver) = unbounded();
86 let watcher = log_notify_error(Watcher::new_immediate(move |event| {
87 watcher_sender.send(event).unwrap()
88 }));
89 self.watcher = watcher.map(|it| (it, watcher_receiver));
90
97 let n_total = config.load.len(); 91 let n_total = config.load.len();
98 self.send(loader::Message::Progress { n_total, n_done: 0 }); 92 self.send(loader::Message::Progress { n_total, n_done: 0 });
99 93
100 self.unwatch_all();
101 self.config.clear(); 94 self.config.clear();
102 95
103 for (i, entry) in config.load.into_iter().enumerate() { 96 for (i, entry) in config.load.into_iter().enumerate() {
@@ -217,16 +210,8 @@ impl NotifyActor {
217 } 210 }
218 211
219 fn watch(&mut self, path: AbsPathBuf) { 212 fn watch(&mut self, path: AbsPathBuf) {
220 if let Some(watcher) = &mut self.watcher { 213 if let Some((watcher, _)) = &mut self.watcher {
221 log_notify_error(watcher.watch(&path, RecursiveMode::NonRecursive)); 214 log_notify_error(watcher.watch(&path, RecursiveMode::NonRecursive));
222 self.watched_paths.insert(path);
223 }
224 }
225 fn unwatch_all(&mut self) {
226 if let Some(watcher) = &mut self.watcher {
227 for path in self.watched_paths.drain() {
228 log_notify_error(watcher.unwatch(path));
229 }
230 } 215 }
231 } 216 }
232 fn send(&mut self, msg: loader::Message) { 217 fn send(&mut self, msg: loader::Message) {