From 9673b8f2a08302c10ffcfd063f2dbdec4301d3e2 Mon Sep 17 00:00:00 2001 From: Zachary Date: Sat, 19 Mar 2022 18:44:30 +0100 Subject: [PATCH] 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. --- egui/src/widgets/slider.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/egui/src/widgets/slider.rs b/egui/src/widgets/slider.rs index 23480abeece..c458c0ed1b8 100644 --- a/egui/src/widgets/slider.rs +++ b/egui/src/widgets/slider.rs @@ -455,10 +455,13 @@ impl<'a> Slider<'a> { fn value_ui(&mut self, ui: &mut Ui, position_range: RangeInclusive) -> 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),