1
0
mirror of https://github.com/emilk/egui.git synced 2026-06-27 07:03:14 -04:00

Fix code that could lead to a possible deadlock.

Drop implementations are not called until the end of a statement. The statement changed in this commit therefore took 4 read locks on a RwLock which can lead to problems if a write lock is requested between any of these read locks. The code looks like it would only hold one lock at a time but it does not drop any of the locks until after the arithmatic operations complete, which leads to this situation. See https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=996079046184329f3a9df1cd19c87da8 to see this in action. The fix is to just take one lock and share it between the three calls to num_presses, letting it drop at the end of the scope.
This commit is contained in:
Zachary
2022-03-19 18:44:30 +01:00
parent 465c96122c
commit 9673b8f2a0

View File

@@ -455,10 +455,13 @@ impl<'a> Slider<'a> {
fn value_ui(&mut self, ui: &mut Ui, position_range: RangeInclusive<f32>) -> Response {
// If `DragValue` is controlled from the keyboard and `step` is defined, set speed to `step`
let change = ui.input().num_presses(Key::ArrowUp) as i32
+ ui.input().num_presses(Key::ArrowRight) as i32
- ui.input().num_presses(Key::ArrowDown) as i32
- ui.input().num_presses(Key::ArrowLeft) as i32;
let change = {
let input = ui.input();
input.num_presses(Key::ArrowUp) as i32 + input.num_presses(Key::ArrowRight) as i32
- input.num_presses(Key::ArrowDown) as i32
- input.num_presses(Key::ArrowLeft) as i32
};
let speed = match self.step {
Some(step) if change != 0 => step,
_ => self.current_gradient(&position_range),