mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-22 01:16:18 +04:00
Use try_lock
in diff_handle
for Diff gutter (#11092)
* Use `try_lock` in `diff_handle` for Diff gutter - Add the method `try_load() -> Option<Diff>` to `DiffHandle`, using `try_lock` to avoid deadlocks. - Use said method in `gutter.rs diff()`, which will use a blank `GutterFn` instead when met with a locked `Diff`. * Revert changes * Replace `Mutex` with `RwLock` in `Diff` --------- Co-authored-by: Kaniel Kirby <pirate7007@runbox.com>
This commit is contained in:
parent
aaaafb8f5f
commit
f0282689da
@ -5,7 +5,7 @@
|
|||||||
use helix_core::Rope;
|
use helix_core::Rope;
|
||||||
use helix_event::RenderLockGuard;
|
use helix_event::RenderLockGuard;
|
||||||
use imara_diff::Algorithm;
|
use imara_diff::Algorithm;
|
||||||
use parking_lot::{Mutex, MutexGuard};
|
use parking_lot::{RwLock, RwLockReadGuard};
|
||||||
use tokio::sync::mpsc::{unbounded_channel, UnboundedSender};
|
use tokio::sync::mpsc::{unbounded_channel, UnboundedSender};
|
||||||
use tokio::task::JoinHandle;
|
use tokio::task::JoinHandle;
|
||||||
use tokio::time::Instant;
|
use tokio::time::Instant;
|
||||||
@ -37,7 +37,7 @@ struct DiffInner {
|
|||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct DiffHandle {
|
pub struct DiffHandle {
|
||||||
channel: UnboundedSender<Event>,
|
channel: UnboundedSender<Event>,
|
||||||
diff: Arc<Mutex<DiffInner>>,
|
diff: Arc<RwLock<DiffInner>>,
|
||||||
inverted: bool,
|
inverted: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ pub fn new(diff_base: Rope, doc: Rope) -> DiffHandle {
|
|||||||
|
|
||||||
fn new_with_handle(diff_base: Rope, doc: Rope) -> (DiffHandle, JoinHandle<()>) {
|
fn new_with_handle(diff_base: Rope, doc: Rope) -> (DiffHandle, JoinHandle<()>) {
|
||||||
let (sender, receiver) = unbounded_channel();
|
let (sender, receiver) = unbounded_channel();
|
||||||
let diff: Arc<Mutex<DiffInner>> = Arc::default();
|
let diff: Arc<RwLock<DiffInner>> = Arc::default();
|
||||||
let worker = DiffWorker {
|
let worker = DiffWorker {
|
||||||
channel: receiver,
|
channel: receiver,
|
||||||
diff: diff.clone(),
|
diff: diff.clone(),
|
||||||
@ -70,7 +70,7 @@ pub fn invert(&mut self) {
|
|||||||
|
|
||||||
pub fn load(&self) -> Diff {
|
pub fn load(&self) -> Diff {
|
||||||
Diff {
|
Diff {
|
||||||
diff: self.diff.lock(),
|
diff: self.diff.read(),
|
||||||
inverted: self.inverted,
|
inverted: self.inverted,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -164,7 +164,7 @@ pub fn is_pure_removal(&self) -> bool {
|
|||||||
/// non-overlapping order
|
/// non-overlapping order
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Diff<'a> {
|
pub struct Diff<'a> {
|
||||||
diff: MutexGuard<'a, DiffInner>,
|
diff: RwLockReadGuard<'a, DiffInner>,
|
||||||
inverted: bool,
|
inverted: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
use helix_core::{Rope, RopeSlice};
|
use helix_core::{Rope, RopeSlice};
|
||||||
use imara_diff::intern::InternedInput;
|
use imara_diff::intern::InternedInput;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::RwLock;
|
||||||
use tokio::sync::mpsc::UnboundedReceiver;
|
use tokio::sync::mpsc::UnboundedReceiver;
|
||||||
use tokio::sync::Notify;
|
use tokio::sync::Notify;
|
||||||
use tokio::time::{timeout, timeout_at, Duration};
|
use tokio::time::{timeout, timeout_at, Duration};
|
||||||
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
pub(super) struct DiffWorker {
|
pub(super) struct DiffWorker {
|
||||||
pub channel: UnboundedReceiver<Event>,
|
pub channel: UnboundedReceiver<Event>,
|
||||||
pub diff: Arc<Mutex<DiffInner>>,
|
pub diff: Arc<RwLock<DiffInner>>,
|
||||||
pub new_hunks: Vec<Hunk>,
|
pub new_hunks: Vec<Hunk>,
|
||||||
pub diff_finished_notify: Arc<Notify>,
|
pub diff_finished_notify: Arc<Notify>,
|
||||||
}
|
}
|
||||||
@ -73,7 +73,7 @@ pub async fn run(mut self, diff_base: Rope, doc: Rope) {
|
|||||||
/// `self.new_hunks` is always empty after this function runs.
|
/// `self.new_hunks` is always empty after this function runs.
|
||||||
/// To improve performance this function tries to reuse the allocation of the old diff previously stored in `self.line_diffs`
|
/// To improve performance this function tries to reuse the allocation of the old diff previously stored in `self.line_diffs`
|
||||||
fn apply_hunks(&mut self, diff_base: Rope, doc: Rope) {
|
fn apply_hunks(&mut self, diff_base: Rope, doc: Rope) {
|
||||||
let mut diff = self.diff.lock();
|
let mut diff = self.diff.write();
|
||||||
diff.diff_base = diff_base;
|
diff.diff_base = diff_base;
|
||||||
diff.doc = doc;
|
diff.doc = doc;
|
||||||
swap(&mut diff.hunks, &mut self.new_hunks);
|
swap(&mut diff.hunks, &mut self.new_hunks);
|
||||||
|
@ -12,7 +12,7 @@ async fn into_diff(self, handle: JoinHandle<()>) -> Vec<Hunk> {
|
|||||||
// dropping the channel terminates the task
|
// dropping the channel terminates the task
|
||||||
drop(self.channel);
|
drop(self.channel);
|
||||||
handle.await.unwrap();
|
handle.await.unwrap();
|
||||||
let diff = diff.lock();
|
let diff = diff.read();
|
||||||
Vec::clone(&diff.hunks)
|
Vec::clone(&diff.hunks)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user