Skip to content

Unregister fds in kill - #245

Merged
ids1024 merged 2 commits into
Smithay:masterfrom
dforsyth:master
Oct 1, 2026
Merged

ids1024 merged 2 commits into
Smithay:masterfrom
dforsyth:master

Conversation

@dforsyth

@dforsyth dforsyth commented Jun 29, 2026 •

Copy link
Copy Markdown
Contributor

On FreeBSD, if we don't call unregister, a stale source is left behind in polling's kqueue implementation.

It becomes impossible to reuse that fd number, resulting in a crash for niri because of an AlreadyExists error (niri-wm/niri#4016).

This change tracks dispatcher registration in register and reregister, and subsequently does unregister (if necessary) when kill is called.

I've only tested this on FreeBSD with niri.

@ids1024

ids1024 commented Oct 1, 2026

Copy link
Copy Markdown
Member

I'm not really familiar with this part of calloop, but calloop::io appears to be used only by LoopHandle::adapt_io. So I guess in Niri this is failing to unregister the FDs used in on_new_ipc_client? Since that's the only place that uses adapt_io.

It would be good to get one or more unit tests for the behavior here.

@ids1024

ids1024 commented Oct 1, 2026

Copy link
Copy Markdown
Member

Looks like a reproduction can be as simple as:

use std::os::unix::net::UnixStream;
use std::rc::Rc;

fn main() {
    let event_loop = calloop::EventLoop::<()>::try_new().unwrap();
    let handle = event_loop.handle();

    let socket = Rc::new(UnixStream::pair().unwrap().0);
    handle.adapt_io(socket.clone()).unwrap();
    handle.adapt_io(socket).unwrap();
};

This seems to panic on the second adapt_io call before this PR, but not after.

@codecov

codecov Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.05882% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 85.99%. Comparing base (9252986) to head (6764929).
⚠️ Report is 15 commits behind head on master.

Files with missing lines Patch % Lines
src/io.rs 97.05% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #245      +/-   ##
==========================================
+ Coverage   85.47%   85.99%   +0.51%     
==========================================
  Files          14       16       +2     
  Lines        1818     1949     +131     
==========================================
+ Hits         1554     1676     +122     
- Misses        264      273       +9     
Flag Coverage Δ
macos-latest 85.36% <97.05%> (?)
ubuntu-latest 85.61% <97.05%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ids1024

ids1024 commented Oct 1, 2026

Copy link
Copy Markdown
Member

Rebased and added 2 unit tests.

Now I understand this and have tests to reproduce this, I'm pretty sure this is correct. Though it looks like src/io.rs could generally use an audit to see if there are issue, or cleaner ways to do things with less unsafe shenanigans.

@ids1024
ids1024 merged commit 49c1f04 into Smithay:master Oct 1, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants