diff options
Diffstat (limited to 'crates/ra_lsp_server/src')
-rw-r--r-- | crates/ra_lsp_server/src/main_loop.rs | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 7fc0b8f50..c43637351 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs | |||
@@ -47,6 +47,8 @@ enum Task { | |||
47 | Notify(RawNotification), | 47 | Notify(RawNotification), |
48 | } | 48 | } |
49 | 49 | ||
50 | const THREADPOOL_SIZE: usize = 8; | ||
51 | |||
50 | pub fn main_loop( | 52 | pub fn main_loop( |
51 | internal_mode: bool, | 53 | internal_mode: bool, |
52 | ws_root: PathBuf, | 54 | ws_root: PathBuf, |
@@ -54,7 +56,7 @@ pub fn main_loop( | |||
54 | msg_receiver: &Receiver<RawMessage>, | 56 | msg_receiver: &Receiver<RawMessage>, |
55 | msg_sender: &Sender<RawMessage>, | 57 | msg_sender: &Sender<RawMessage>, |
56 | ) -> Result<()> { | 58 | ) -> Result<()> { |
57 | let pool = ThreadPool::new(8); | 59 | let pool = ThreadPool::new(THREADPOOL_SIZE); |
58 | let (task_sender, task_receiver) = unbounded::<Task>(); | 60 | let (task_sender, task_receiver) = unbounded::<Task>(); |
59 | let (ws_worker, ws_watcher) = workspace_loader(); | 61 | let (ws_worker, ws_watcher) = workspace_loader(); |
60 | 62 | ||
@@ -164,6 +166,11 @@ fn main_loop_inner( | |||
164 | pending_requests: &mut FxHashSet<u64>, | 166 | pending_requests: &mut FxHashSet<u64>, |
165 | subs: &mut Subscriptions, | 167 | subs: &mut Subscriptions, |
166 | ) -> Result<()> { | 168 | ) -> Result<()> { |
169 | // We try not to index more than THREADPOOL_SIZE - 3 libraries at the same | ||
170 | // time to always have a thread ready to react to input. | ||
171 | let mut in_flight_libraries = 0; | ||
172 | let mut pending_libraries = Vec::new(); | ||
173 | |||
167 | let (libdata_sender, libdata_receiver) = unbounded(); | 174 | let (libdata_sender, libdata_receiver) = unbounded(); |
168 | loop { | 175 | loop { |
169 | log::trace!("selecting"); | 176 | log::trace!("selecting"); |
@@ -191,6 +198,7 @@ fn main_loop_inner( | |||
191 | Event::Lib(lib) => { | 198 | Event::Lib(lib) => { |
192 | feedback(internal_mode, "library loaded", msg_sender); | 199 | feedback(internal_mode, "library loaded", msg_sender); |
193 | state.add_lib(lib); | 200 | state.add_lib(lib); |
201 | in_flight_libraries -= 1; | ||
194 | } | 202 | } |
195 | Event::Msg(msg) => match msg { | 203 | Event::Msg(msg) => match msg { |
196 | RawMessage::Request(req) => { | 204 | RawMessage::Request(req) => { |
@@ -219,8 +227,10 @@ fn main_loop_inner( | |||
219 | }, | 227 | }, |
220 | }; | 228 | }; |
221 | 229 | ||
222 | for lib in state.process_changes() { | 230 | pending_libraries.extend(state.process_changes()); |
223 | let (root, files) = lib; | 231 | while in_flight_libraries < THREADPOOL_SIZE - 3 && !pending_libraries.is_empty() { |
232 | let (root, files) = pending_libraries.pop().unwrap(); | ||
233 | in_flight_libraries += 1; | ||
224 | let sender = libdata_sender.clone(); | 234 | let sender = libdata_sender.clone(); |
225 | pool.execute(move || { | 235 | pool.execute(move || { |
226 | let start = ::std::time::Instant::now(); | 236 | let start = ::std::time::Instant::now(); |
@@ -230,7 +240,8 @@ fn main_loop_inner( | |||
230 | sender.send(data).unwrap(); | 240 | sender.send(data).unwrap(); |
231 | }); | 241 | }); |
232 | } | 242 | } |
233 | if state.roots_to_scan == 0 { | 243 | |
244 | if state.roots_to_scan == 0 && pending_libraries.is_empty() && in_flight_libraries == 0 { | ||
234 | feedback(internal_mode, "workspace loaded", msg_sender); | 245 | feedback(internal_mode, "workspace loaded", msg_sender); |
235 | } | 246 | } |
236 | 247 | ||