diff options
| author | Isaac Freund <mail@isaacfreund.com> | 2023-01-07 14:58:28 +0100 |
|---|---|---|
| committer | Isaac Freund <mail@isaacfreund.com> | 2023-01-07 14:58:28 +0100 |
| commit | f511a34dedfd5b3bed5bd9d078530adf4c26c83c (patch) | |
| tree | 396e8b5e1424fc5cd44bf1e547ceefeea2c2b973 | |
| parent | df2fc30238fe445cf04aaf64d0b906195129f726 (diff) | |
| download | river-f511a34dedfd5b3bed5bd9d078530adf4c26c83c.tar.gz river-f511a34dedfd5b3bed5bd9d078530adf4c26c83c.tar.xz | |
session-lock: fix assertion failure due to race
There's currently a potential race in the implementation that can be hit
during unlocking. This is not a security vulnerability, but it does
cause the compositor to crash due to a failed assertion.
This commit simplifies the code and fixes the race as well as tightening
up the assertions around this state/control flow even further.
| -rw-r--r-- | river/Output.zig | 4 | ||||
| -rw-r--r-- | river/render.zig | 13 |
2 files changed, 12 insertions, 5 deletions
diff --git a/river/Output.zig b/river/Output.zig index 0d5a541..b14247a 100644 --- a/river/Output.zig +++ b/river/Output.zig @@ -530,7 +530,7 @@ fn handlePresent( const self = @fieldParentPtr(Self, "present", listener); switch (self.lock_render_state) { - .unlocked => return, + .unlocked => assert(server.lock_manager.state != .locked), .pending_blank, .pending_lock_surface => { if (!event.presented) { self.lock_render_state = .unlocked; @@ -548,7 +548,7 @@ fn handlePresent( server.lock_manager.maybeLock(); } }, - .blanked, .lock_surface => unreachable, + .blanked, .lock_surface => {}, } } diff --git a/river/render.zig b/river/render.zig index a238cd9..6c1280c 100644 --- a/river/render.zig +++ b/river/render.zig @@ -98,10 +98,17 @@ pub fn renderOutput(output: *Output) void { return; }; - if (output.lock_surface == null) { - output.lock_render_state = .pending_blank; + if (server.lock_manager.state == .locked) { + switch (output.lock_render_state) { + .unlocked, .pending_blank, .pending_lock_surface => unreachable, + .blanked, .lock_surface => {}, + } } else { - output.lock_render_state = .pending_lock_surface; + if (output.lock_surface == null) { + output.lock_render_state = .pending_blank; + } else { + output.lock_render_state = .pending_lock_surface; + } } return; |
