diff options
-rw-r--r-- | crates/ra_vfs/src/io.rs | 24 |
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}; | |||
9 | use relative_path::RelativePathBuf; | 9 | use relative_path::RelativePathBuf; |
10 | use thread_worker::WorkerHandle; | 10 | use thread_worker::WorkerHandle; |
11 | use walkdir::WalkDir; | 11 | use walkdir::WalkDir; |
12 | use parking_lot::Mutex; | ||
13 | use notify::{DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher as _Watcher}; | 12 | use notify::{DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher as _Watcher}; |
14 | 13 | ||
15 | use crate::{RootConfig, Roots, VfsRoot}; | 14 | use 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 | ||
145 | fn watch_root(woker: &WatcherCtx, root: VfsRoot, config: Arc<RootConfig>) { | 144 | fn 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)] | ||
164 | struct WatcherCtx { | 161 | struct 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 | ||
200 | impl WatcherCtx { | 197 | impl 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 | } |