diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-03-30 10:33:43 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-03-30 10:33:43 +0100 |
commit | df8752bf3f92f657eb89ba86888c1b8b94c5e8d9 (patch) | |
tree | 2f46877e85c6a10b810dd6ff2a0e0c680c800bda | |
parent | 846cbe7d4eb0a5f1b1c943180fdf03b81ede1f24 (diff) | |
parent | 12297ab67533200748ee9f60da4bc86dee1133d9 (diff) |
Merge #3754
3754: Use automatic thread joining for cargo-watch r=matklad a=matklad
r? @kiljacken
Co-authored-by: Aleksey Kladov <[email protected]>
-rw-r--r-- | Cargo.lock | 5 | ||||
-rw-r--r-- | crates/ra_cargo_watch/Cargo.toml | 1 | ||||
-rw-r--r-- | crates/ra_cargo_watch/src/lib.rs | 50 | ||||
-rw-r--r-- | crates/ra_prof/src/lib.rs | 8 | ||||
-rw-r--r-- | crates/rust-analyzer/tests/heavy_tests/support.rs | 3 |
5 files changed, 23 insertions, 44 deletions
diff --git a/Cargo.lock b/Cargo.lock index 8d81c4839..a3887ce99 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -563,9 +563,9 @@ dependencies = [ | |||
563 | 563 | ||
564 | [[package]] | 564 | [[package]] |
565 | name = "jod-thread" | 565 | name = "jod-thread" |
566 | version = "0.1.0" | 566 | version = "0.1.1" |
567 | source = "registry+https://github.com/rust-lang/crates.io-index" | 567 | source = "registry+https://github.com/rust-lang/crates.io-index" |
568 | checksum = "2f52a11f73b88fab829a0e4d9e13ea5982c7ac457c72eb3541d82a4afdfce4ff" | 568 | checksum = "4022656272c3e564a7cdebcaaba6518d844b0d0c1836597196efb5bfeb98bb49" |
569 | 569 | ||
570 | [[package]] | 570 | [[package]] |
571 | name = "kernel32-sys" | 571 | name = "kernel32-sys" |
@@ -893,6 +893,7 @@ dependencies = [ | |||
893 | "cargo_metadata", | 893 | "cargo_metadata", |
894 | "crossbeam-channel", | 894 | "crossbeam-channel", |
895 | "insta", | 895 | "insta", |
896 | "jod-thread", | ||
896 | "log", | 897 | "log", |
897 | "lsp-types", | 898 | "lsp-types", |
898 | "serde_json", | 899 | "serde_json", |
diff --git a/crates/ra_cargo_watch/Cargo.toml b/crates/ra_cargo_watch/Cargo.toml index 741345a21..300033a18 100644 --- a/crates/ra_cargo_watch/Cargo.toml +++ b/crates/ra_cargo_watch/Cargo.toml | |||
@@ -10,6 +10,7 @@ lsp-types = { version = "0.73.0", features = ["proposed"] } | |||
10 | log = "0.4.8" | 10 | log = "0.4.8" |
11 | cargo_metadata = "0.9.1" | 11 | cargo_metadata = "0.9.1" |
12 | serde_json = "1.0.48" | 12 | serde_json = "1.0.48" |
13 | jod-thread = "0.1.1" | ||
13 | 14 | ||
14 | [dev-dependencies] | 15 | [dev-dependencies] |
15 | insta = "0.15.0" | 16 | insta = "0.15.0" |
diff --git a/crates/ra_cargo_watch/src/lib.rs b/crates/ra_cargo_watch/src/lib.rs index 7c525c430..1cac954c3 100644 --- a/crates/ra_cargo_watch/src/lib.rs +++ b/crates/ra_cargo_watch/src/lib.rs | |||
@@ -12,7 +12,6 @@ use std::{ | |||
12 | io::{BufRead, BufReader}, | 12 | io::{BufRead, BufReader}, |
13 | path::{Path, PathBuf}, | 13 | path::{Path, PathBuf}, |
14 | process::{Command, Stdio}, | 14 | process::{Command, Stdio}, |
15 | thread::JoinHandle, | ||
16 | time::Instant, | 15 | time::Instant, |
17 | }; | 16 | }; |
18 | 17 | ||
@@ -36,9 +35,10 @@ pub struct CheckOptions { | |||
36 | /// The spawned thread is shut down when this struct is dropped. | 35 | /// The spawned thread is shut down when this struct is dropped. |
37 | #[derive(Debug)] | 36 | #[derive(Debug)] |
38 | pub struct CheckWatcher { | 37 | pub struct CheckWatcher { |
39 | pub task_recv: Receiver<CheckTask>, | 38 | // XXX: drop order is significant |
40 | cmd_send: Option<Sender<CheckCommand>>, | 39 | cmd_send: Option<Sender<CheckCommand>>, |
41 | handle: Option<JoinHandle<()>>, | 40 | handle: Option<jod_thread::JoinHandle<()>>, |
41 | pub task_recv: Receiver<CheckTask>, | ||
42 | } | 42 | } |
43 | 43 | ||
44 | impl CheckWatcher { | 44 | impl CheckWatcher { |
@@ -47,7 +47,7 @@ impl CheckWatcher { | |||
47 | 47 | ||
48 | let (task_send, task_recv) = unbounded::<CheckTask>(); | 48 | let (task_send, task_recv) = unbounded::<CheckTask>(); |
49 | let (cmd_send, cmd_recv) = unbounded::<CheckCommand>(); | 49 | let (cmd_send, cmd_recv) = unbounded::<CheckCommand>(); |
50 | let handle = std::thread::spawn(move || { | 50 | let handle = jod_thread::spawn(move || { |
51 | let mut check = CheckWatcherThread::new(options, workspace_root); | 51 | let mut check = CheckWatcherThread::new(options, workspace_root); |
52 | check.run(&task_send, &cmd_recv); | 52 | check.run(&task_send, &cmd_recv); |
53 | }); | 53 | }); |
@@ -67,22 +67,6 @@ impl CheckWatcher { | |||
67 | } | 67 | } |
68 | } | 68 | } |
69 | 69 | ||
70 | impl std::ops::Drop for CheckWatcher { | ||
71 | fn drop(&mut self) { | ||
72 | if let Some(handle) = self.handle.take() { | ||
73 | // Take the sender out of the option | ||
74 | let cmd_send = self.cmd_send.take(); | ||
75 | |||
76 | // Dropping the sender finishes the thread loop | ||
77 | drop(cmd_send); | ||
78 | |||
79 | // Join the thread, it should finish shortly. We don't really care | ||
80 | // whether it panicked, so it is safe to ignore the result | ||
81 | let _ = handle.join(); | ||
82 | } | ||
83 | } | ||
84 | } | ||
85 | |||
86 | #[derive(Debug)] | 70 | #[derive(Debug)] |
87 | pub enum CheckTask { | 71 | pub enum CheckTask { |
88 | /// Request a clearing of all cached diagnostics from the check watcher | 72 | /// Request a clearing of all cached diagnostics from the check watcher |
@@ -237,8 +221,9 @@ pub struct DiagnosticWithFixes { | |||
237 | /// The correct way to dispose of the thread is to drop it, on which the | 221 | /// The correct way to dispose of the thread is to drop it, on which the |
238 | /// sub-process will be killed, and the thread will be joined. | 222 | /// sub-process will be killed, and the thread will be joined. |
239 | struct WatchThread { | 223 | struct WatchThread { |
240 | handle: Option<JoinHandle<()>>, | 224 | // XXX: drop order is significant |
241 | message_recv: Receiver<CheckEvent>, | 225 | message_recv: Receiver<CheckEvent>, |
226 | _handle: Option<jod_thread::JoinHandle<()>>, | ||
242 | } | 227 | } |
243 | 228 | ||
244 | enum CheckEvent { | 229 | enum CheckEvent { |
@@ -333,7 +318,7 @@ pub fn run_cargo( | |||
333 | 318 | ||
334 | impl WatchThread { | 319 | impl WatchThread { |
335 | fn dummy() -> WatchThread { | 320 | fn dummy() -> WatchThread { |
336 | WatchThread { handle: None, message_recv: never() } | 321 | WatchThread { message_recv: never(), _handle: None } |
337 | } | 322 | } |
338 | 323 | ||
339 | fn new(options: &CheckOptions, workspace_root: &Path) -> WatchThread { | 324 | fn new(options: &CheckOptions, workspace_root: &Path) -> WatchThread { |
@@ -352,7 +337,7 @@ impl WatchThread { | |||
352 | let (message_send, message_recv) = unbounded(); | 337 | let (message_send, message_recv) = unbounded(); |
353 | let workspace_root = workspace_root.to_owned(); | 338 | let workspace_root = workspace_root.to_owned(); |
354 | let handle = if options.enable { | 339 | let handle = if options.enable { |
355 | Some(std::thread::spawn(move || { | 340 | Some(jod_thread::spawn(move || { |
356 | // If we trigger an error here, we will do so in the loop instead, | 341 | // If we trigger an error here, we will do so in the loop instead, |
357 | // which will break out of the loop, and continue the shutdown | 342 | // which will break out of the loop, and continue the shutdown |
358 | let _ = message_send.send(CheckEvent::Begin); | 343 | let _ = message_send.send(CheckEvent::Begin); |
@@ -383,23 +368,6 @@ impl WatchThread { | |||
383 | } else { | 368 | } else { |
384 | None | 369 | None |
385 | }; | 370 | }; |
386 | WatchThread { handle, message_recv } | 371 | WatchThread { message_recv, _handle: handle } |
387 | } | ||
388 | } | ||
389 | |||
390 | impl std::ops::Drop for WatchThread { | ||
391 | fn drop(&mut self) { | ||
392 | if let Some(handle) = self.handle.take() { | ||
393 | // Replace our reciever with dummy one, so we can drop and close the | ||
394 | // one actually communicating with the thread | ||
395 | let recv = std::mem::replace(&mut self.message_recv, never()); | ||
396 | |||
397 | // Dropping the original reciever initiates thread sub-process shutdown | ||
398 | drop(recv); | ||
399 | |||
400 | // Join the thread, it should finish shortly. We don't really care | ||
401 | // whether it panicked, so it is safe to ignore the result | ||
402 | let _ = handle.join(); | ||
403 | } | ||
404 | } | 372 | } |
405 | } | 373 | } |
diff --git a/crates/ra_prof/src/lib.rs b/crates/ra_prof/src/lib.rs index 9e167db96..00ea3a9b0 100644 --- a/crates/ra_prof/src/lib.rs +++ b/crates/ra_prof/src/lib.rs | |||
@@ -339,6 +339,14 @@ pub fn print_backtrace() { | |||
339 | let bt = backtrace::Backtrace::new(); | 339 | let bt = backtrace::Backtrace::new(); |
340 | eprintln!("{:?}", bt); | 340 | eprintln!("{:?}", bt); |
341 | } | 341 | } |
342 | #[cfg(not(feature = "backtrace"))] | ||
343 | pub fn print_backtrace() { | ||
344 | eprintln!( | ||
345 | r#"enable the backtrace feature: | ||
346 | ra_prof = {{ path = "../ra_prof", features = [ "backtrace"] }} | ||
347 | "# | ||
348 | ); | ||
349 | } | ||
342 | 350 | ||
343 | thread_local!(static IN_SCOPE: RefCell<bool> = RefCell::new(false)); | 351 | thread_local!(static IN_SCOPE: RefCell<bool> = RefCell::new(false)); |
344 | 352 | ||
diff --git a/crates/rust-analyzer/tests/heavy_tests/support.rs b/crates/rust-analyzer/tests/heavy_tests/support.rs index 1d7062bdf..67f3c9332 100644 --- a/crates/rust-analyzer/tests/heavy_tests/support.rs +++ b/crates/rust-analyzer/tests/heavy_tests/support.rs | |||
@@ -83,9 +83,10 @@ pub fn project(fixture: &str) -> Server { | |||
83 | pub struct Server { | 83 | pub struct Server { |
84 | req_id: Cell<u64>, | 84 | req_id: Cell<u64>, |
85 | messages: RefCell<Vec<Message>>, | 85 | messages: RefCell<Vec<Message>>, |
86 | dir: TempDir, | ||
87 | _thread: jod_thread::JoinHandle<()>, | 86 | _thread: jod_thread::JoinHandle<()>, |
88 | client: Connection, | 87 | client: Connection, |
88 | /// XXX: remove the tempdir last | ||
89 | dir: TempDir, | ||
89 | } | 90 | } |
90 | 91 | ||
91 | impl Server { | 92 | impl Server { |