Switch from Arc/RwLock to Rc/RefCell for CodeContextMenu (#22035)

`CodeContextMenu` is always accessed on one thread, so only `Rc`s and
`Rc<RefCell<_>>` are needed. There should be tiny performance benefits
from this. The main benefit of this is that when seeing code accessing a
`RwLock` it would be reasonable to wonder whether it will block. The
only potential downside is the potential for panics due to overlapping
borrows of the RefCells. I think this is an acceptable risk because most
errors of this nature will be local or will be caught by clippy via the
check for holding a RefCell reference over an `await`.

Release Notes:

- N/A
This commit is contained in:
Michael Sloan
2024-12-16 01:50:21 -07:00
committed by GitHub
parent 7b721efe2c
commit a94afbc062
12 changed files with 108 additions and 93 deletions
+16 -14
View File
@@ -52,7 +52,7 @@ use lsp::{
WillRenameFiles, WorkDoneProgressCancelParams, WorkspaceFolder,
};
use node_runtime::read_package_installed_version;
use parking_lot::{Mutex, RwLock};
use parking_lot::Mutex;
use postage::watch;
use rand::prelude::*;
@@ -65,12 +65,14 @@ use smol::channel::Sender;
use snippet::Snippet;
use std::{
any::Any,
cell::RefCell,
cmp::Ordering,
convert::TryInto,
ffi::OsStr,
iter, mem,
ops::{ControlFlow, Range},
path::{self, Path, PathBuf},
rc::Rc,
str,
sync::Arc,
time::{Duration, Instant},
@@ -4137,7 +4139,7 @@ impl LspStore {
&self,
buffer: Model<Buffer>,
completion_indices: Vec<usize>,
completions: Arc<RwLock<Box<[Completion]>>>,
completions: Rc<RefCell<Box<[Completion]>>>,
cx: &mut ModelContext<Self>,
) -> Task<Result<bool>> {
let client = self.upstream_client();
@@ -4151,8 +4153,8 @@ impl LspStore {
if let Some((client, project_id)) = client {
for completion_index in completion_indices {
let (server_id, completion) = {
let completions_guard = completions.read();
let completion = &completions_guard[completion_index];
let completions = completions.borrow_mut();
let completion = &completions[completion_index];
did_resolve = true;
let server_id = completion.server_id;
let completion = completion.lsp_completion.clone();
@@ -4175,8 +4177,8 @@ impl LspStore {
} else {
for completion_index in completion_indices {
let (server_id, completion) = {
let completions_guard = completions.read();
let completion = &completions_guard[completion_index];
let completions = completions.borrow_mut();
let completion = &completions[completion_index];
let server_id = completion.server_id;
let completion = completion.lsp_completion.clone();
@@ -4218,7 +4220,7 @@ impl LspStore {
server: Arc<lsp::LanguageServer>,
adapter: Arc<CachedLspAdapter>,
snapshot: &BufferSnapshot,
completions: Arc<RwLock<Box<[Completion]>>>,
completions: Rc<RefCell<Box<[Completion]>>>,
completion_index: usize,
completion: lsp::CompletionItem,
language_registry: Arc<LanguageRegistry>,
@@ -4246,11 +4248,11 @@ impl LspStore {
)
.await;
let mut completions = completions.write();
let mut completions = completions.borrow_mut();
let completion = &mut completions[completion_index];
completion.documentation = Some(documentation);
} else {
let mut completions = completions.write();
let mut completions = completions.borrow_mut();
let completion = &mut completions[completion_index];
completion.documentation = Some(Documentation::Undocumented);
}
@@ -4265,7 +4267,7 @@ impl LspStore {
if let Some((old_range, mut new_text)) = edit {
LineEnding::normalize(&mut new_text);
let mut completions = completions.write();
let mut completions = completions.borrow_mut();
let completion = &mut completions[completion_index];
completion.new_text = new_text;
@@ -4274,7 +4276,7 @@ impl LspStore {
}
if completion_item.insert_text_format == Some(InsertTextFormat::SNIPPET) {
// vtsls might change the type of completion after resolution.
let mut completions = completions.write();
let mut completions = completions.borrow_mut();
let completion = &mut completions[completion_index];
if completion_item.insert_text_format != completion.lsp_completion.insert_text_format {
completion.lsp_completion.insert_text_format = completion_item.insert_text_format;
@@ -4300,7 +4302,7 @@ impl LspStore {
)
});
let mut completions = completions.write();
let mut completions = completions.borrow_mut();
let completion = &mut completions[completion_index];
completion.lsp_completion = completion_item;
if completion.label.filter_text() == new_label.filter_text() {
@@ -4322,7 +4324,7 @@ impl LspStore {
project_id: u64,
server_id: LanguageServerId,
buffer_id: BufferId,
completions: Arc<RwLock<Box<[Completion]>>>,
completions: Rc<RefCell<Box<[Completion]>>>,
completion_index: usize,
completion: lsp::CompletionItem,
client: AnyProtoClient,
@@ -4360,7 +4362,7 @@ impl LspStore {
Documentation::MultiLinePlainText(response.documentation)
};
let mut completions = completions.write();
let mut completions = completions.borrow_mut();
let completion = &mut completions[completion_index];
completion.documentation = Some(documentation);
completion.lsp_completion = lsp_completion;
+4 -2
View File
@@ -57,7 +57,7 @@ use lsp::{
};
use lsp_command::*;
use node_runtime::NodeRuntime;
use parking_lot::{Mutex, RwLock};
use parking_lot::Mutex;
pub use prettier_store::PrettierStore;
use project_settings::{ProjectSettings, SettingsObserver, SettingsObserverEvent};
use remote::{SshConnectionOptions, SshRemoteClient};
@@ -73,8 +73,10 @@ use snippet::Snippet;
use snippet_provider::SnippetProvider;
use std::{
borrow::Cow,
cell::RefCell,
ops::Range,
path::{Component, Path, PathBuf},
rc::Rc,
str,
sync::Arc,
time::Duration,
@@ -2872,7 +2874,7 @@ impl Project {
&self,
buffer: Model<Buffer>,
completion_indices: Vec<usize>,
completions: Arc<RwLock<Box<[Completion]>>>,
completions: Rc<RefCell<Box<[Completion]>>>,
cx: &mut ModelContext<Self>,
) -> Task<Result<bool>> {
self.lsp_store.update(cx, |lsp_store, cx| {