aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_vfs/src/io.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_vfs/src/io.rs')
-rw-r--r--crates/ra_vfs/src/io.rs24
1 files changed, 10 insertions, 14 deletions
diff --git a/crates/ra_vfs/src/io.rs b/crates/ra_vfs/src/io.rs
index 98b107b35..8c719dc5d 100644
--- a/crates/ra_vfs/src/io.rs
+++ b/crates/ra_vfs/src/io.rs
@@ -9,7 +9,6 @@ use crossbeam_channel::{Receiver, Sender, unbounded, RecvError, select};
9use relative_path::RelativePathBuf; 9use relative_path::RelativePathBuf;
10use thread_worker::WorkerHandle; 10use thread_worker::WorkerHandle;
11use walkdir::WalkDir; 11use walkdir::WalkDir;
12use parking_lot::Mutex;
13use notify::{DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher as _Watcher}; 12use notify::{DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher as _Watcher};
14 13
15use crate::{RootConfig, Roots, VfsRoot}; 14use crate::{RootConfig, Roots, VfsRoot};
@@ -83,9 +82,9 @@ impl Worker {
83 let watcher = notify::watcher(notify_sender, WATCHER_DELAY) 82 let watcher = notify::watcher(notify_sender, WATCHER_DELAY)
84 .map_err(|e| log::error!("failed to spawn notify {}", e)) 83 .map_err(|e| log::error!("failed to spawn notify {}", e))
85 .ok(); 84 .ok();
86 let ctx = WatcherCtx { 85 let mut ctx = WatcherCtx {
87 roots, 86 roots,
88 watcher: Arc::new(Mutex::new(watcher)), 87 watcher,
89 sender: output_sender, 88 sender: output_sender,
90 }; 89 };
91 let thread = thread::spawn(move || { 90 let thread = thread::spawn(move || {
@@ -101,18 +100,18 @@ impl Worker {
101 // closed, we should shutdown everything. 100 // closed, we should shutdown everything.
102 recv(input_receiver) -> t => match t { 101 recv(input_receiver) -> t => match t {
103 Err(RecvError) => break, 102 Err(RecvError) => break,
104 Ok(Task::AddRoot { root, config }) => watch_root(&ctx, root, Arc::clone(&config)), 103 Ok(Task::AddRoot { root, config }) => watch_root(&mut ctx, root, Arc::clone(&config)),
105 }, 104 },
106 // Watcher send us changes. If **this** channel is 105 // Watcher send us changes. If **this** channel is
107 // closed, the watcher has died, which indicates a bug 106 // closed, the watcher has died, which indicates a bug
108 // -- escalate! 107 // -- escalate!
109 recv(watcher_receiver) -> event => match event { 108 recv(watcher_receiver) -> event => match event {
110 Err(RecvError) => panic!("watcher is dead"), 109 Err(RecvError) => panic!("watcher is dead"),
111 Ok((path, change)) => WatcherCtx::handle_change(&ctx, path, change).unwrap(), 110 Ok((path, change)) => WatcherCtx::handle_change(&mut ctx, path, change).unwrap(),
112 }, 111 },
113 } 112 }
114 } 113 }
115 drop(ctx.watcher.lock().take()); 114 drop(ctx.watcher.take());
116 drop(ctx); 115 drop(ctx);
117 let res2 = thread.join(); 116 let res2 = thread.join();
118 match &res2 { 117 match &res2 {
@@ -142,10 +141,9 @@ impl Worker {
142 } 141 }
143} 142}
144 143
145fn watch_root(woker: &WatcherCtx, root: VfsRoot, config: Arc<RootConfig>) { 144fn watch_root(woker: &mut WatcherCtx, root: VfsRoot, config: Arc<RootConfig>) {
146 let mut guard = woker.watcher.lock();
147 log::debug!("loading {} ...", config.root.as_path().display()); 145 log::debug!("loading {} ...", config.root.as_path().display());
148 let files = watch_recursive(guard.as_mut(), config.root.as_path(), &*config) 146 let files = watch_recursive(woker.watcher.as_mut(), config.root.as_path(), &*config)
149 .into_iter() 147 .into_iter()
150 .filter_map(|path| { 148 .filter_map(|path| {
151 let abs_path = path.to_path(&config.root); 149 let abs_path = path.to_path(&config.root);
@@ -160,10 +158,9 @@ fn watch_root(woker: &WatcherCtx, root: VfsRoot, config: Arc<RootConfig>) {
160 log::debug!("... loaded {}", config.root.as_path().display()); 158 log::debug!("... loaded {}", config.root.as_path().display());
161} 159}
162 160
163#[derive(Clone)]
164struct WatcherCtx { 161struct WatcherCtx {
165 roots: Arc<Roots>, 162 roots: Arc<Roots>,
166 watcher: Arc<Mutex<Option<RecommendedWatcher>>>, 163 watcher: Option<RecommendedWatcher>,
167 sender: Sender<TaskResult>, 164 sender: Sender<TaskResult>,
168} 165}
169 166
@@ -198,7 +195,7 @@ fn convert_notify_event(event: DebouncedEvent, sender: &Sender<(PathBuf, ChangeK
198} 195}
199 196
200impl WatcherCtx { 197impl WatcherCtx {
201 fn handle_change(&self, path: PathBuf, kind: ChangeKind) -> Result<()> { 198 fn handle_change(&mut self, path: PathBuf, kind: ChangeKind) -> Result<()> {
202 let (root, rel_path) = match self.roots.find(&path) { 199 let (root, rel_path) = match self.roots.find(&path) {
203 None => return Ok(()), 200 None => return Ok(()),
204 Some(it) => it, 201 Some(it) => it,
@@ -208,8 +205,7 @@ impl WatcherCtx {
208 ChangeKind::Create => { 205 ChangeKind::Create => {
209 let mut paths = Vec::new(); 206 let mut paths = Vec::new();
210 if path.is_dir() { 207 if path.is_dir() {
211 let mut guard = self.watcher.lock(); 208 paths.extend(watch_recursive(self.watcher.as_mut(), &path, &config));
212 paths.extend(watch_recursive(guard.as_mut(), &path, &config));
213 } else { 209 } else {
214 paths.push(rel_path); 210 paths.push(rel_path);
215 } 211 }