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
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 108 additions and 93 deletions

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;

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| {