Skip to content

Commit c0b5eb4

Browse files
committed
Use automatic thread joining for cargo-watch
1 parent 6415c82 commit c0b5eb4

File tree

3 files changed

+10
-40
lines changed

3 files changed

+10
-40
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ra_cargo_watch/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ lsp-types = { version = "0.73.0", features = ["proposed"] }
1010
log = "0.4.8"
1111
cargo_metadata = "0.9.1"
1212
serde_json = "1.0.48"
13+
jod-thread = "0.1.1"
1314

1415
[dev-dependencies]
1516
insta = "0.15.0"

crates/ra_cargo_watch/src/lib.rs

+8-40
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use std::{
1212
io::{BufRead, BufReader},
1313
path::{Path, PathBuf},
1414
process::{Command, Stdio},
15-
thread::JoinHandle,
1615
time::Instant,
1716
};
1817

@@ -37,8 +36,9 @@ pub struct CheckOptions {
3736
#[derive(Debug)]
3837
pub struct CheckWatcher {
3938
pub task_recv: Receiver<CheckTask>,
39+
// XXX: drop order is significant
4040
cmd_send: Option<Sender<CheckCommand>>,
41-
handle: Option<JoinHandle<()>>,
41+
handle: Option<jod_thread::JoinHandle<()>>,
4242
}
4343

4444
impl CheckWatcher {
@@ -47,7 +47,7 @@ impl CheckWatcher {
4747

4848
let (task_send, task_recv) = unbounded::<CheckTask>();
4949
let (cmd_send, cmd_recv) = unbounded::<CheckCommand>();
50-
let handle = std::thread::spawn(move || {
50+
let handle = jod_thread::spawn(move || {
5151
let mut check = CheckWatcherThread::new(options, workspace_root);
5252
check.run(&task_send, &cmd_recv);
5353
});
@@ -67,22 +67,6 @@ impl CheckWatcher {
6767
}
6868
}
6969

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-
8670
#[derive(Debug)]
8771
pub enum CheckTask {
8872
/// Request a clearing of all cached diagnostics from the check watcher
@@ -237,8 +221,9 @@ pub struct DiagnosticWithFixes {
237221
/// The correct way to dispose of the thread is to drop it, on which the
238222
/// sub-process will be killed, and the thread will be joined.
239223
struct WatchThread {
240-
handle: Option<JoinHandle<()>>,
224+
// XXX: drop order is significant
241225
message_recv: Receiver<CheckEvent>,
226+
_handle: Option<jod_thread::JoinHandle<()>>,
242227
}
243228

244229
enum CheckEvent {
@@ -333,7 +318,7 @@ pub fn run_cargo(
333318

334319
impl WatchThread {
335320
fn dummy() -> WatchThread {
336-
WatchThread { handle: None, message_recv: never() }
321+
WatchThread { message_recv: never(), _handle: None }
337322
}
338323

339324
fn new(options: &CheckOptions, workspace_root: &Path) -> WatchThread {
@@ -352,7 +337,7 @@ impl WatchThread {
352337
let (message_send, message_recv) = unbounded();
353338
let workspace_root = workspace_root.to_owned();
354339
let handle = if options.enable {
355-
Some(std::thread::spawn(move || {
340+
Some(jod_thread::spawn(move || {
356341
// If we trigger an error here, we will do so in the loop instead,
357342
// which will break out of the loop, and continue the shutdown
358343
let _ = message_send.send(CheckEvent::Begin);
@@ -383,23 +368,6 @@ impl WatchThread {
383368
} else {
384369
None
385370
};
386-
WatchThread { handle, message_recv }
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-
}
371+
WatchThread { message_recv, _handle: handle }
404372
}
405373
}

0 commit comments

Comments
 (0)