mirror of
https://github.com/games-on-whales/gst-wayland-display.git
synced 2026-10-15 12:51:57 +00:00
[PR #60] fix(compositor): close the seat keymap memfd at session teardown #61
Labels
No labels
enhancement
enhancement
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
games-on-whales/gst-wayland-display#61
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/games-on-whales/gst-wayland-display/pull/60
Author: @salty2011
Created: 8/19/2026
Status: 🔄 Open
Base:
stable← Head:fix/keymap-memfd-teardown📝 Commits (1)
6ab6dbcfix(compositor): close the seat keymap memfd at session teardown📊 Changes
3 files changed (+205 additions, -1 deletions)
View changed files
📝
wayland-display-core/src/comp/mod.rs(+42 -1)📝
wayland-display-core/src/tests/mod.rs(+1 -0)➕
wayland-display-core/src/tests/test_keymap_fd.rs(+162 -0)📄 Description
Problem
smithay mints one sealed
memfd:smithay-keymapperSeat::add_keyboardand keeps it in theArc<KbdRc>behind the seat'sKeyboardHandle. DroppingStatecloses it only when no grab is left installed.The cycle:
KbdRc(input/keyboard/mod.rs,KbdInternal::grab).PopupKeyboardGrabwraps aPopupGrabwhosekeyboard_handleis exactly that clone.xdg_popup.grab(wayland/handlers/xdg.rs).So a grab still active when the session ends is an
Arcpointing at itself, and the fd stays open for the life of the process. The escape hatches do not save it: the stale-grab discard inwith_grabandPopupKeyboardGrab'shas_ended()unset both run on the next grab access, which never comes once the session is over.Measured on a workload whose clients routinely end a session with a popup grab open: 136 back-to-back sessions, exactly one leaked fd each, slope 1.00/cycle with no plateau. Everything else the compositor owns was released on schedule, including the sibling
smithay-dmabuffeedback-format-tablememfd in the sameDisplay, which is what rules out a leakedStateorDisplay. At ~50 sessions a day a host crosses the 1024 fd soft limit in under a month and new sessions fail withEMFILE.Fix
State::release_seat, called once the event loop stops: unset any surviving grab (this is what breaks the cycle), clear keyboard focus, drop the seat's handle. The fd closes deterministically rather than depending on the client having torn its popups down politely.Tests
Count the process's open
smithay-keymapmemfds across 8 teardowns, once plainly and once with a grab ofPopupGrab's retaining shape installed. Neuteringrelease_seatfails the grab test and leaves the plain one passing, which is the expected split since the plain case has no cycle to leak.The count is process-global while cargo runs this binary's tests in parallel, so the post-cycle sample is the lowest of several readings. A leak is permanent and survives every sample; a neighbouring test's fixture is not. Without that, the two tests contaminate each other's baseline.
Known gap
Neither test goes through
comp::init, so the production call site is wired but not covered. Deleting the call would leave the suite green.Upstream candidate
The deeper fix belongs in smithay: hold the grab's
KeyboardHandleweakly, or unset the grab when the last non-grab reference goes away. This is the compositor-side workaround.Verified
cargo fmtclean,cargo checkclean, 25 tests pass.🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.