Re: Kqueues and fork
Konstantin Belousov <[email protected]> Fri, 29 Aug 2025 17:27:04 +0300
| Newsgroups | gmane.os.freebsd.architechture |
|---|---|
| Message-ID | <[email protected]> |
On Fri, Aug 29, 2025 at 01:57:52PM +0300, Gleb Popov wrote: > On Wed, Aug 20, 2025 at 2:12 PM Konstantin Belousov <[email protected]> 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()