aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_lsp_server
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-02-14 17:43:45 +0000
committerAleksey Kladov <[email protected]>2019-02-14 18:11:07 +0000
commitbf352cd2511775a331d77dee261b64bd8359dacb (patch)
treeba7d988ebef437d5a9d7beac048b5ac0dbd2fe9c /crates/ra_lsp_server
parent10bf61b83b2600ed3cb7e7825f1cd0ee83e9b7e7 (diff)
automatically wait for worker threads
closes #817
Diffstat (limited to 'crates/ra_lsp_server')
-rw-r--r--crates/ra_lsp_server/src/main_loop.rs26
-rw-r--r--crates/ra_lsp_server/src/project_model.rs6
-rw-r--r--crates/ra_lsp_server/tests/heavy_tests/support.rs17
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
105enum Event { 103enum 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 @@
1use std::path::PathBuf; 1use std::path::PathBuf;
2 2
3use thread_worker::{WorkerHandle, Worker}; 3use thread_worker::Worker;
4 4
5use crate::Result; 5use 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
11pub fn workspace_loader() -> (Worker<PathBuf, Result<ProjectWorkspace>>, WorkerHandle) { 11pub 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::{
17use serde::Serialize; 17use serde::Serialize;
18use serde_json::{to_string_pretty, Value}; 18use serde_json::{to_string_pretty, Value};
19use tempfile::TempDir; 19use tempfile::TempDir;
20use thread_worker::{WorkerHandle, Worker}; 20use thread_worker::Worker;
21use test_utils::{parse_fixture, find_mismatch}; 21use test_utils::{parse_fixture, find_mismatch};
22 22
23use ra_lsp_server::{ 23use 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
51impl Server { 50impl 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
170impl Drop for Server { 168impl 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