git.lucas.co / cce-compositor
Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git

commit178c4c371a0430236e608877ce8112b094328b02
parent39c1d6879c
authorIsaac Freund <[email protected]>
date2023-03-01 11:33
session-lock: fix race with multiple outputs

The race is as follows:
1. Output A commits and sets render state to pending_lock_surface
2. Output B commits and sets render state to pending_lock_surface
3. Output A presents and sets render state to lock_surface
4. maybeLock() does not lock because waiting on output B
5. Output A commits and sets render state to pending_lock_surface
6. Output B presents and sets render state to lock_surface
4. maybeLock() does not lock because waiting on output A

 river/Output.zig | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/river/Output.zig b/river/Output.zig
index b92a4e2..e300598 100644
--- a/river/Output.zig
+++ b/river/Output.zig
@@ -428,8 +428,16 @@ fn handleFrame(listener: *wl.Listener(*wlr.Output), _: *wlr.Output) void {
                     .unlocked, .pending_blank, .pending_lock_surface => unreachable,
                     .blanked, .lock_surface => {},
                 },
-                .waiting_for_blank => output.lock_render_state = .pending_blank,
-                .waiting_for_lock_surfaces => output.lock_render_state = .pending_lock_surface,
+                .waiting_for_blank => {
+                    if (output.lock_render_state != .blanked) {
+                        output.lock_render_state = .pending_blank;
+                    }
+                },
+                .waiting_for_lock_surfaces => {
+                    if (output.lock_render_state != .lock_surface) {
+                        output.lock_render_state = .pending_lock_surface;
+                    }
+                },
             }
         }
     } else {