Skip to content

Commit 8a4c248

Browse files
bors[bot]kiljacken
andauthored
Merge #2898
2898: Remove RWLock from check watcher. r=matklad a=kiljacken @matklad mentioned this might be a good idea. So the general idea is that we don't really need the lock, as we can just clone the check watcher state when creating a snapshot. We can then use `Arc::get_mut` to get mutable access to the state from `WorldState` when needed. Running with this it seems to improve responsiveness a bit while cargo is running, but I have no hard numbers to prove it. In any case, a serialization point less is always better when we're trying to be responsive. Co-authored-by: Emil Lauridsen <[email protected]>
2 parents 2fb8a46 + 05aa5b8 commit 8a4c248

File tree

5 files changed

+16
-18
lines changed

5 files changed

+16
-18
lines changed

crates/ra_cargo_watch/src/conv.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ fn is_deprecated(rd: &RustDiagnostic) -> bool {
117117
}
118118
}
119119

120-
#[derive(Debug)]
120+
#[derive(Clone, Debug)]
121121
pub struct SuggestedFix {
122122
pub title: String,
123123
pub location: Location,

crates/ra_cargo_watch/src/lib.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use lsp_types::{
77
Diagnostic, Url, WorkDoneProgress, WorkDoneProgressBegin, WorkDoneProgressEnd,
88
WorkDoneProgressReport,
99
};
10-
use parking_lot::RwLock;
1110
use std::{
1211
collections::HashMap,
1312
path::PathBuf,
@@ -38,15 +37,15 @@ pub struct CheckOptions {
3837
#[derive(Debug)]
3938
pub struct CheckWatcher {
4039
pub task_recv: Receiver<CheckTask>,
41-
pub state: Arc<RwLock<CheckState>>,
40+
pub state: Arc<CheckState>,
4241
cmd_send: Option<Sender<CheckCommand>>,
4342
handle: Option<JoinHandle<()>>,
4443
}
4544

4645
impl CheckWatcher {
4746
pub fn new(options: &CheckOptions, workspace_root: PathBuf) -> CheckWatcher {
4847
let options = options.clone();
49-
let state = Arc::new(RwLock::new(CheckState::new()));
48+
let state = Arc::new(CheckState::new());
5049

5150
let (task_send, task_recv) = unbounded::<CheckTask>();
5251
let (cmd_send, cmd_recv) = unbounded::<CheckCommand>();
@@ -59,7 +58,7 @@ impl CheckWatcher {
5958

6059
/// Returns a CheckWatcher that doesn't actually do anything
6160
pub fn dummy() -> CheckWatcher {
62-
let state = Arc::new(RwLock::new(CheckState::new()));
61+
let state = Arc::new(CheckState::new());
6362
CheckWatcher { task_recv: never(), cmd_send: None, handle: None, state }
6463
}
6564

@@ -87,7 +86,7 @@ impl std::ops::Drop for CheckWatcher {
8786
}
8887
}
8988

90-
#[derive(Debug)]
89+
#[derive(Clone, Debug)]
9190
pub struct CheckState {
9291
diagnostic_collection: HashMap<Url, Vec<Diagnostic>>,
9392
suggested_fix_collection: HashMap<Url, Vec<SuggestedFix>>,

crates/ra_lsp_server/src/main_loop.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -586,12 +586,14 @@ fn on_notification(
586586

587587
fn on_check_task(
588588
task: CheckTask,
589-
world_state: &WorldState,
589+
world_state: &mut WorldState,
590590
task_sender: &Sender<Task>,
591591
) -> Result<()> {
592592
match task {
593593
CheckTask::ClearDiagnostics => {
594-
let cleared_files = world_state.check_watcher.state.write().clear();
594+
let state = Arc::get_mut(&mut world_state.check_watcher.state)
595+
.expect("couldn't get check watcher state as mutable");
596+
let cleared_files = state.clear();
595597

596598
// Send updated diagnostics for each cleared file
597599
for url in cleared_files {
@@ -600,11 +602,9 @@ fn on_check_task(
600602
}
601603

602604
CheckTask::AddDiagnostic(url, diagnostic) => {
603-
world_state
604-
.check_watcher
605-
.state
606-
.write()
607-
.add_diagnostic_with_fixes(url.clone(), diagnostic);
605+
let state = Arc::get_mut(&mut world_state.check_watcher.state)
606+
.expect("couldn't get check watcher state as mutable");
607+
state.add_diagnostic_with_fixes(url.clone(), diagnostic);
608608

609609
// We manually send a diagnostic update when the watcher asks
610610
// us to, to avoid the issue of having to change the file to

crates/ra_lsp_server/src/main_loop/handlers.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -674,8 +674,7 @@ pub fn handle_code_action(
674674
res.push(action.into());
675675
}
676676

677-
for fix in world.check_watcher.read().fixes_for(&params.text_document.uri).into_iter().flatten()
678-
{
677+
for fix in world.check_watcher.fixes_for(&params.text_document.uri).into_iter().flatten() {
679678
let fix_range = fix.location.range.conv_with(&line_index);
680679
if fix_range.intersection(&range).is_none() {
681680
continue;
@@ -895,7 +894,7 @@ pub fn publish_diagnostics(
895894
tags: None,
896895
})
897896
.collect();
898-
if let Some(check_diags) = world.check_watcher.read().diagnostics_for(&uri) {
897+
if let Some(check_diags) = world.check_watcher.diagnostics_for(&uri) {
899898
diagnostics.extend(check_diags.iter().cloned());
900899
}
901900
Ok(req::PublishDiagnosticsParams { uri, diagnostics, version: None })

crates/ra_lsp_server/src/world.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ pub struct WorldSnapshot {
6363
pub workspaces: Arc<Vec<ProjectWorkspace>>,
6464
pub analysis: Analysis,
6565
pub latest_requests: Arc<RwLock<LatestRequests>>,
66-
pub check_watcher: Arc<RwLock<CheckState>>,
66+
pub check_watcher: CheckState,
6767
vfs: Arc<RwLock<Vfs>>,
6868
}
6969

@@ -220,7 +220,7 @@ impl WorldState {
220220
analysis: self.analysis_host.analysis(),
221221
vfs: Arc::clone(&self.vfs),
222222
latest_requests: Arc::clone(&self.latest_requests),
223-
check_watcher: self.check_watcher.state.clone(),
223+
check_watcher: (*self.check_watcher.state).clone(),
224224
}
225225
}
226226

0 commit comments

Comments
 (0)