aboutsummaryrefslogtreecommitdiff
path: root/crates/vfs-notify
diff options
context:
space:
mode:
Diffstat (limited to 'crates/vfs-notify')
-rw-r--r--crates/vfs-notify/src/lib.rs56
1 files changed, 26 insertions, 30 deletions
diff --git a/crates/vfs-notify/src/lib.rs b/crates/vfs-notify/src/lib.rs
index baee6ddc8..25ba8d798 100644
--- a/crates/vfs-notify/src/lib.rs
+++ b/crates/vfs-notify/src/lib.rs
@@ -20,7 +20,7 @@ use walkdir::WalkDir;
20use crate::include::Include; 20use crate::include::Include;
21 21
22#[derive(Debug)] 22#[derive(Debug)]
23pub struct LoaderHandle { 23pub struct NotifyHandle {
24 // Relative order of fields below is significant. 24 // Relative order of fields below is significant.
25 sender: crossbeam_channel::Sender<Message>, 25 sender: crossbeam_channel::Sender<Message>,
26 _thread: jod_thread::JoinHandle, 26 _thread: jod_thread::JoinHandle,
@@ -32,12 +32,12 @@ enum Message {
32 Invalidate(AbsPathBuf), 32 Invalidate(AbsPathBuf),
33} 33}
34 34
35impl loader::Handle for LoaderHandle { 35impl loader::Handle for NotifyHandle {
36 fn spawn(sender: loader::Sender) -> LoaderHandle { 36 fn spawn(sender: loader::Sender) -> NotifyHandle {
37 let actor = LoaderActor::new(sender); 37 let actor = NotifyActor::new(sender);
38 let (sender, receiver) = unbounded::<Message>(); 38 let (sender, receiver) = unbounded::<Message>();
39 let thread = jod_thread::spawn(move || actor.run(receiver)); 39 let thread = jod_thread::spawn(move || actor.run(receiver));
40 LoaderHandle { sender, _thread: thread } 40 NotifyHandle { sender, _thread: thread }
41 } 41 }
42 fn set_config(&mut self, config: loader::Config) { 42 fn set_config(&mut self, config: loader::Config) {
43 self.sender.send(Message::Config(config)).unwrap() 43 self.sender.send(Message::Config(config)).unwrap()
@@ -45,17 +45,17 @@ impl loader::Handle for LoaderHandle {
45 fn invalidate(&mut self, path: AbsPathBuf) { 45 fn invalidate(&mut self, path: AbsPathBuf) {
46 self.sender.send(Message::Invalidate(path)).unwrap(); 46 self.sender.send(Message::Invalidate(path)).unwrap();
47 } 47 }
48 fn load_sync(&mut self, path: &AbsPathBuf) -> Option<Vec<u8>> { 48 fn load_sync(&mut self, path: &AbsPath) -> Option<Vec<u8>> {
49 read(path) 49 read(path)
50 } 50 }
51} 51}
52 52
53type NotifyEvent = notify::Result<notify::Event>; 53type NotifyEvent = notify::Result<notify::Event>;
54 54
55struct LoaderActor { 55struct NotifyActor {
56 sender: loader::Sender,
56 config: Vec<(AbsPathBuf, Include, bool)>, 57 config: Vec<(AbsPathBuf, Include, bool)>,
57 watched_paths: FxHashSet<AbsPathBuf>, 58 watched_paths: FxHashSet<AbsPathBuf>,
58 sender: loader::Sender,
59 // Drop order of fields bellow is significant, 59 // Drop order of fields bellow is significant,
60 watcher: Option<RecommendedWatcher>, 60 watcher: Option<RecommendedWatcher>,
61 watcher_receiver: Receiver<NotifyEvent>, 61 watcher_receiver: Receiver<NotifyEvent>,
@@ -67,30 +67,35 @@ enum Event {
67 NotifyEvent(NotifyEvent), 67 NotifyEvent(NotifyEvent),
68} 68}
69 69
70impl LoaderActor { 70impl NotifyActor {
71 fn new(sender: loader::Sender) -> LoaderActor { 71 fn new(sender: loader::Sender) -> NotifyActor {
72 let (watcher_sender, watcher_receiver) = unbounded(); 72 let (watcher_sender, watcher_receiver) = unbounded();
73 let watcher = log_notify_error(Watcher::new_immediate(move |event| { 73 let watcher = log_notify_error(Watcher::new_immediate(move |event| {
74 watcher_sender.send(event).unwrap() 74 watcher_sender.send(event).unwrap()
75 })); 75 }));
76 76
77 LoaderActor { 77 NotifyActor {
78 watcher,
79 watcher_receiver,
80 watched_paths: FxHashSet::default(),
81 sender, 78 sender,
82 config: Vec::new(), 79 config: Vec::new(),
80 watched_paths: FxHashSet::default(),
81 watcher,
82 watcher_receiver,
83 } 83 }
84 } 84 }
85 85 fn next_event(&self, receiver: &Receiver<Message>) -> Option<Event> {
86 fn run(mut self, receiver: Receiver<Message>) { 86 select! {
87 while let Some(event) = self.next_event(&receiver) { 87 recv(receiver) -> it => it.ok().map(Event::Message),
88 recv(&self.watcher_receiver) -> it => Some(Event::NotifyEvent(it.unwrap())),
89 }
90 }
91 fn run(mut self, inbox: Receiver<Message>) {
92 while let Some(event) = self.next_event(&inbox) {
88 log::debug!("vfs-notify event: {:?}", event); 93 log::debug!("vfs-notify event: {:?}", event);
89 match event { 94 match event {
90 Event::Message(msg) => match msg { 95 Event::Message(msg) => match msg {
91 Message::Config(config) => { 96 Message::Config(config) => {
92 let n_entries_total = config.load.len(); 97 let n_total = config.load.len();
93 self.send(loader::Message::Progress { n_entries_total, n_entries_done: 0 }); 98 self.send(loader::Message::Progress { n_total, n_done: 0 });
94 99
95 self.unwatch_all(); 100 self.unwatch_all();
96 self.config.clear(); 101 self.config.clear();
@@ -99,10 +104,7 @@ impl LoaderActor {
99 let watch = config.watch.contains(&i); 104 let watch = config.watch.contains(&i);
100 let files = self.load_entry(entry, watch); 105 let files = self.load_entry(entry, watch);
101 self.send(loader::Message::Loaded { files }); 106 self.send(loader::Message::Loaded { files });
102 self.send(loader::Message::Progress { 107 self.send(loader::Message::Progress { n_total, n_done: i + 1 });
103 n_entries_total,
104 n_entries_done: i + 1,
105 });
106 } 108 }
107 self.config.sort_by(|x, y| x.0.cmp(&y.0)); 109 self.config.sort_by(|x, y| x.0.cmp(&y.0));
108 } 110 }
@@ -157,12 +159,6 @@ impl LoaderActor {
157 } 159 }
158 } 160 }
159 } 161 }
160 fn next_event(&self, receiver: &Receiver<Message>) -> Option<Event> {
161 select! {
162 recv(receiver) -> it => it.ok().map(Event::Message),
163 recv(&self.watcher_receiver) -> it => Some(Event::NotifyEvent(it.unwrap())),
164 }
165 }
166 fn load_entry( 162 fn load_entry(
167 &mut self, 163 &mut self,
168 entry: loader::Entry, 164 entry: loader::Entry,
@@ -199,7 +195,7 @@ impl LoaderActor {
199 let is_dir = entry.file_type().is_dir(); 195 let is_dir = entry.file_type().is_dir();
200 let is_file = entry.file_type().is_file(); 196 let is_file = entry.file_type().is_file();
201 let abs_path = AbsPathBuf::try_from(entry.into_path()).unwrap(); 197 let abs_path = AbsPathBuf::try_from(entry.into_path()).unwrap();
202 if is_dir { 198 if is_dir && watch {
203 self.watch(abs_path.clone()); 199 self.watch(abs_path.clone());
204 } 200 }
205 let rel_path = abs_path.strip_prefix(&path)?; 201 let rel_path = abs_path.strip_prefix(&path)?;