aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-03-30 10:33:43 +0100
committerGitHub <[email protected]>2020-03-30 10:33:43 +0100
commitdf8752bf3f92f657eb89ba86888c1b8b94c5e8d9 (patch)
tree2f46877e85c6a10b810dd6ff2a0e0c680c800bda
parent846cbe7d4eb0a5f1b1c943180fdf03b81ede1f24 (diff)
parent12297ab67533200748ee9f60da4bc86dee1133d9 (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.lock5
-rw-r--r--crates/ra_cargo_watch/Cargo.toml1
-rw-r--r--crates/ra_cargo_watch/src/lib.rs50
-rw-r--r--crates/ra_prof/src/lib.rs8
-rw-r--r--crates/rust-analyzer/tests/heavy_tests/support.rs3
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]]
565name = "jod-thread" 565name = "jod-thread"
566version = "0.1.0" 566version = "0.1.1"
567source = "registry+https://github.com/rust-lang/crates.io-index" 567source = "registry+https://github.com/rust-lang/crates.io-index"
568checksum = "2f52a11f73b88fab829a0e4d9e13ea5982c7ac457c72eb3541d82a4afdfce4ff" 568checksum = "4022656272c3e564a7cdebcaaba6518d844b0d0c1836597196efb5bfeb98bb49"
569 569
570[[package]] 570[[package]]
571name = "kernel32-sys" 571name = "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"] }
10log = "0.4.8" 10log = "0.4.8"
11cargo_metadata = "0.9.1" 11cargo_metadata = "0.9.1"
12serde_json = "1.0.48" 12serde_json = "1.0.48"
13jod-thread = "0.1.1"
13 14
14[dev-dependencies] 15[dev-dependencies]
15insta = "0.15.0" 16insta = "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)]
38pub struct CheckWatcher { 37pub 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
44impl CheckWatcher { 44impl 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
70impl 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)]
87pub enum CheckTask { 71pub 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.
239struct WatchThread { 223struct 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
244enum CheckEvent { 229enum CheckEvent {
@@ -333,7 +318,7 @@ pub fn run_cargo(
333 318
334impl WatchThread { 319impl 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
390impl 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"))]
343pub fn print_backtrace() {
344 eprintln!(
345 r#"enable the backtrace feature:
346 ra_prof = {{ path = "../ra_prof", features = [ "backtrace"] }}
347"#
348 );
349}
342 350
343thread_local!(static IN_SCOPE: RefCell<bool> = RefCell::new(false)); 351thread_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 {
83pub struct Server { 83pub 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
91impl Server { 92impl Server {