diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/vfs-notify/src/lib.rs | 43 |
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 | ||
11 | use std::convert::{TryFrom, TryInto}; | 11 | use std::convert::{TryFrom, TryInto}; |
12 | 12 | ||
13 | use crossbeam_channel::{select, unbounded, Receiver, Sender}; | 13 | use crossbeam_channel::{never, select, unbounded, Receiver, Sender}; |
14 | use notify::{RecommendedWatcher, RecursiveMode, Watcher}; | 14 | use notify::{RecommendedWatcher, RecursiveMode, Watcher}; |
15 | use paths::{AbsPath, AbsPathBuf}; | 15 | use paths::{AbsPath, AbsPathBuf}; |
16 | use rustc_hash::FxHashSet; | ||
17 | use vfs::loader; | 16 | use vfs::loader; |
18 | use walkdir::WalkDir; | 17 | use walkdir::WalkDir; |
19 | 18 | ||
@@ -55,10 +54,8 @@ type NotifyEvent = notify::Result<notify::Event>; | |||
55 | struct NotifyActor { | 54 | struct 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 | ||
70 | impl NotifyActor { | 67 | impl 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) { |