diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-02-14 18:22:19 +0000 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-02-14 18:22:19 +0000 |
commit | c530f04df51459d6d5f70c475e93127217f6e27f (patch) | |
tree | 2e9abadb6e64fed7738b5b3fbc2eb13787efdaca /crates/ra_lsp_server | |
parent | 10bf61b83b2600ed3cb7e7825f1cd0ee83e9b7e7 (diff) | |
parent | e0b8942c56378b7966af39058f27b11a0d02890f (diff) |
Merge #833
833: automatically wait for worker threads r=matklad a=matklad
closes #817
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_lsp_server')
-rw-r--r-- | crates/ra_lsp_server/src/main_loop.rs | 26 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/project_model.rs | 6 | ||||
-rw-r--r-- | crates/ra_lsp_server/tests/heavy_tests/support.rs | 17 |
3 files changed, 20 insertions, 29 deletions
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index a51299851..06443bb76 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs | |||
@@ -54,19 +54,20 @@ pub fn main_loop( | |||
54 | ) -> Result<()> { | 54 | ) -> Result<()> { |
55 | let pool = ThreadPool::new(THREADPOOL_SIZE); | 55 | let pool = ThreadPool::new(THREADPOOL_SIZE); |
56 | let (task_sender, task_receiver) = unbounded::<Task>(); | 56 | let (task_sender, task_receiver) = unbounded::<Task>(); |
57 | let (ws_worker, ws_watcher) = workspace_loader(); | ||
58 | 57 | ||
59 | ws_worker.send(ws_root.clone()).unwrap(); | ||
60 | // FIXME: support dynamic workspace loading. | 58 | // FIXME: support dynamic workspace loading. |
61 | let workspaces = match ws_worker.recv().unwrap() { | 59 | let workspaces = { |
62 | Ok(ws) => vec![ws], | 60 | let ws_worker = workspace_loader(); |
63 | Err(e) => { | 61 | ws_worker.sender().send(ws_root.clone()).unwrap(); |
64 | log::error!("loading workspace failed: {}", e); | 62 | match ws_worker.receiver().recv().unwrap() { |
65 | Vec::new() | 63 | Ok(ws) => vec![ws], |
64 | Err(e) => { | ||
65 | log::error!("loading workspace failed: {}", e); | ||
66 | Vec::new() | ||
67 | } | ||
66 | } | 68 | } |
67 | }; | 69 | }; |
68 | ws_worker.shutdown(); | 70 | |
69 | ws_watcher.shutdown().map_err(|_| format_err!("ws watcher died"))?; | ||
70 | let mut state = ServerWorldState::new(ws_root.clone(), workspaces); | 71 | let mut state = ServerWorldState::new(ws_root.clone(), workspaces); |
71 | 72 | ||
72 | log::info!("server initialized, serving requests"); | 73 | log::info!("server initialized, serving requests"); |
@@ -94,12 +95,9 @@ pub fn main_loop( | |||
94 | log::info!("...threadpool has finished"); | 95 | log::info!("...threadpool has finished"); |
95 | 96 | ||
96 | let vfs = Arc::try_unwrap(state.vfs).expect("all snapshots should be dead"); | 97 | let vfs = Arc::try_unwrap(state.vfs).expect("all snapshots should be dead"); |
97 | let vfs_res = vfs.into_inner().shutdown(); | 98 | drop(vfs); |
98 | 99 | ||
99 | main_res?; | 100 | main_res |
100 | vfs_res.map_err(|_| format_err!("fs watcher died"))?; | ||
101 | |||
102 | Ok(()) | ||
103 | } | 101 | } |
104 | 102 | ||
105 | enum Event { | 103 | enum Event { |
diff --git a/crates/ra_lsp_server/src/project_model.rs b/crates/ra_lsp_server/src/project_model.rs index 6800eb138..7d6440fad 100644 --- a/crates/ra_lsp_server/src/project_model.rs +++ b/crates/ra_lsp_server/src/project_model.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use std::path::PathBuf; | 1 | use std::path::PathBuf; |
2 | 2 | ||
3 | use thread_worker::{WorkerHandle, Worker}; | 3 | use thread_worker::Worker; |
4 | 4 | ||
5 | use crate::Result; | 5 | use crate::Result; |
6 | 6 | ||
@@ -8,8 +8,8 @@ pub use ra_project_model::{ | |||
8 | ProjectWorkspace, CargoWorkspace, Package, Target, TargetKind, Sysroot, | 8 | ProjectWorkspace, CargoWorkspace, Package, Target, TargetKind, Sysroot, |
9 | }; | 9 | }; |
10 | 10 | ||
11 | pub fn workspace_loader() -> (Worker<PathBuf, Result<ProjectWorkspace>>, WorkerHandle) { | 11 | pub fn workspace_loader() -> Worker<PathBuf, Result<ProjectWorkspace>> { |
12 | thread_worker::spawn::<PathBuf, Result<ProjectWorkspace>, _>( | 12 | Worker::<PathBuf, Result<ProjectWorkspace>>::spawn( |
13 | "workspace loader", | 13 | "workspace loader", |
14 | 1, | 14 | 1, |
15 | |input_receiver, output_sender| { | 15 | |input_receiver, output_sender| { |
diff --git a/crates/ra_lsp_server/tests/heavy_tests/support.rs b/crates/ra_lsp_server/tests/heavy_tests/support.rs index eee85f8c8..11f94b4ab 100644 --- a/crates/ra_lsp_server/tests/heavy_tests/support.rs +++ b/crates/ra_lsp_server/tests/heavy_tests/support.rs | |||
@@ -17,7 +17,7 @@ use lsp_types::{ | |||
17 | use serde::Serialize; | 17 | use serde::Serialize; |
18 | use serde_json::{to_string_pretty, Value}; | 18 | use serde_json::{to_string_pretty, Value}; |
19 | use tempfile::TempDir; | 19 | use tempfile::TempDir; |
20 | use thread_worker::{WorkerHandle, Worker}; | 20 | use thread_worker::Worker; |
21 | use test_utils::{parse_fixture, find_mismatch}; | 21 | use test_utils::{parse_fixture, find_mismatch}; |
22 | 22 | ||
23 | use ra_lsp_server::{ | 23 | use ra_lsp_server::{ |
@@ -45,13 +45,12 @@ pub struct Server { | |||
45 | messages: RefCell<Vec<RawMessage>>, | 45 | messages: RefCell<Vec<RawMessage>>, |
46 | dir: TempDir, | 46 | dir: TempDir, |
47 | worker: Option<Worker<RawMessage, RawMessage>>, | 47 | worker: Option<Worker<RawMessage, RawMessage>>, |
48 | watcher: Option<WorkerHandle>, | ||
49 | } | 48 | } |
50 | 49 | ||
51 | impl Server { | 50 | impl Server { |
52 | fn new(dir: TempDir, files: Vec<(PathBuf, String)>) -> Server { | 51 | fn new(dir: TempDir, files: Vec<(PathBuf, String)>) -> Server { |
53 | let path = dir.path().to_path_buf(); | 52 | let path = dir.path().to_path_buf(); |
54 | let (worker, watcher) = thread_worker::spawn::<RawMessage, RawMessage, _>( | 53 | let worker = Worker::<RawMessage, RawMessage>::spawn( |
55 | "test server", | 54 | "test server", |
56 | 128, | 55 | 128, |
57 | move |mut msg_receiver, mut msg_sender| { | 56 | move |mut msg_receiver, mut msg_sender| { |
@@ -63,7 +62,6 @@ impl Server { | |||
63 | dir, | 62 | dir, |
64 | messages: Default::default(), | 63 | messages: Default::default(), |
65 | worker: Some(worker), | 64 | worker: Some(worker), |
66 | watcher: Some(watcher), | ||
67 | }; | 65 | }; |
68 | 66 | ||
69 | for (path, text) in files { | 67 | for (path, text) in files { |
@@ -117,7 +115,7 @@ impl Server { | |||
117 | } | 115 | } |
118 | fn send_request_(&self, r: RawRequest) -> Value { | 116 | fn send_request_(&self, r: RawRequest) -> Value { |
119 | let id = r.id; | 117 | let id = r.id; |
120 | self.worker.as_ref().unwrap().send(RawMessage::Request(r)).unwrap(); | 118 | self.worker.as_ref().unwrap().sender().send(RawMessage::Request(r)).unwrap(); |
121 | while let Some(msg) = self.recv() { | 119 | while let Some(msg) = self.recv() { |
122 | match msg { | 120 | match msg { |
123 | RawMessage::Request(req) => panic!("unexpected request: {:?}", req), | 121 | RawMessage::Request(req) => panic!("unexpected request: {:?}", req), |
@@ -157,24 +155,19 @@ impl Server { | |||
157 | } | 155 | } |
158 | } | 156 | } |
159 | fn recv(&self) -> Option<RawMessage> { | 157 | fn recv(&self) -> Option<RawMessage> { |
160 | recv_timeout(&self.worker.as_ref().unwrap().out).map(|msg| { | 158 | recv_timeout(&self.worker.as_ref().unwrap().receiver()).map(|msg| { |
161 | self.messages.borrow_mut().push(msg.clone()); | 159 | self.messages.borrow_mut().push(msg.clone()); |
162 | msg | 160 | msg |
163 | }) | 161 | }) |
164 | } | 162 | } |
165 | fn send_notification(&self, not: RawNotification) { | 163 | fn send_notification(&self, not: RawNotification) { |
166 | self.worker.as_ref().unwrap().send(RawMessage::Notification(not)).unwrap(); | 164 | self.worker.as_ref().unwrap().sender().send(RawMessage::Notification(not)).unwrap(); |
167 | } | 165 | } |
168 | } | 166 | } |
169 | 167 | ||
170 | impl Drop for Server { | 168 | impl Drop for Server { |
171 | fn drop(&mut self) { | 169 | fn drop(&mut self) { |
172 | self.send_request::<Shutdown>(()); | 170 | self.send_request::<Shutdown>(()); |
173 | let receiver = self.worker.take().unwrap().shutdown(); | ||
174 | while let Some(msg) = recv_timeout(&receiver) { | ||
175 | drop(msg); | ||
176 | } | ||
177 | self.watcher.take().unwrap().shutdown().unwrap(); | ||
178 | } | 171 | } |
179 | } | 172 | } |
180 | 173 | ||