Re: Kqueues and fork
- Reply: Gleb Popov : "Re: Kqueues and fork"
- In reply to: Gleb Popov : "Re: Kqueues and fork"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 29 Aug 2025 14:27:04 UTC
On Fri, Aug 29, 2025 at 01:57:52PM +0300, Gleb Popov wrote:
> On Wed, Aug 20, 2025 at 2:12 PM Konstantin Belousov <kostikbel@gmail.com> wrote:
> >
> > Is this what the app writers want?
>
> I was one of those who asked Konstantin about this feature.
>
> My context is the dbus-daemon program, which is essentially an RPC
> server working over unix sockets.
> It has an abstraction called "pollable set" that is implemented via
> epoll(7) on Linux and poll(2) as a fallback.
> I developed the kqueue(2) based implementation which was
> straightforward, but then I bumped into
> the mentioned difference on fork.
>
> The daemon does basically this:
>
> parent: kqueuex(0x1) = 3 (0x3)
> parent: fork()
> parent: bind(4,{ AF_UNIX "/var/run/dbus/system_bus_socket" },33)
> parent: listen(4,128)
> parent: kevent(3, { 4,EVFILT_READ}, ... )
>
> child: connect(...) = 5
> child: kevent(3,{ 5,EVFILT_READ}, ... )
Then why don't you just open another kqueue in the child, for the
kqueue-based implementation? If wanted, you can dup2() it into the
same fd as the parent kqueue fd.
>
> This obviously doesn't work for kqueue without KQUEUE_CPONFORK, but
> works for Linux, because epoll fds are
> inherited by children by default. At the same time dbus-daemon doesn't
> really need any intricate events sharing.
>
> My theory is that the code is written this way simply because the
> software is primarily developed on Linux and
> dbus-daemon authors didn't notice that they are leaking the epoll fd
> into the child. I imagine that there might be
> other software in the wild that accidentally shares the epoll fd.
>
> With Konstantin's patch (and after some bugfixing on my side of
> things) the kqueue-based implementation worked
> flawlessly. All the extensive dbus tests pass with no overhead. The
> proposed KQUEUE_CPONFORK flag
> would also be really useful for the devel/libepoll-shim library, which
> tries its best to emulate epoll(7) via kqueue(2),
> but can't do anything about consumers that expect the fd to live after
> calling fork()