Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use try_lock in diff_handle for Diff gutter #11092

Merged
merged 3 commits into from
Aug 9, 2024

Conversation

kanielrkirby
Copy link
Contributor

@kanielrkirby kanielrkirby commented Jul 5, 2024

The situation currently is that render_gutter builds out a Vec of LineDecorations, where LineDecoration is a closure. These don't get evaluated until actually rendering, so the MutexGuard in diff_handle.load() doesn't go out of scope before being accessed again.

This PR does the following:

  • Adds 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.

Fixes #11027.

- 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`.
Copy link
Member

@pascalkuthe pascalkuthe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not the right solution. This will make any diff gutters but the first one blank and will also randomly fail to render the diff gutter if the mutex is locked from the diff worker.

A proper fix would be using an RW lock or a change to the diff infrastructure so resource acquisition can be separate from the rendering closure.

I consider this issue really niche and easy to work around (just don't use multiple diff gutters) so I didn't prioritize fixing this

@kanielrkirby
Copy link
Contributor Author

@pascalkuthe Appreciate the review, I hadn't considered the diff worker. I was mostly trying to avoid the complete deadlock, but this is probably too niche for a patch fix.

If you think it's still worth working on, I'll try reworking it, otherwise I can drop the PR altogether.

@pascalkuthe
Copy link
Member

I guess using a (parking lot) rwlock is an ok solution for now that will add some overhead but it shouldn't be too bad

@the-mikedavis the-mikedavis added the A-vcs Area: Version control system interaction label Jul 5, 2024
@kanielrkirby
Copy link
Contributor Author

Apologies for starting with the dirty solution first, but I appreciate the guidance @pascalkuthe! I'll keep on with this project to see if I can improve with this. On the bright side, now we can do this monstrosity!

20240705-144404

@archseer archseer merged commit f028268 into helix-editor:master Aug 9, 2024
6 checks passed
mxxntype pushed a commit to mxxntype/helix that referenced this pull request Aug 14, 2024
* 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 <[email protected]>
GNUSheep pushed a commit to GNUSheep/helix that referenced this pull request Aug 19, 2024
* 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 <[email protected]>
kyruzic pushed a commit to kyruzic/helix that referenced this pull request Sep 27, 2024
* 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 <[email protected]>
plul pushed a commit to plul/helix that referenced this pull request Oct 13, 2024
* 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 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-vcs Area: Version control system interaction
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Using diff in gutters twice makes Helix get stuck
4 participants