Date: Wed, 4 Jun 2025 12:49:44 +0100 From: Bob Bishop <rb@gid.co.uk> To: Gleb Popov <arrowd@FreeBSD.org> Cc: freebsd-hackers <freebsd-hackers@FreeBSD.org> Subject: Re: Behavioral difference between Linux and FreeBSD poll() Message-ID: <B9BBB7F3-6984-4180-85D1-D5298A278F13@gid.co.uk> In-Reply-To: <CALH631mtKV=0z0Pj83GZ%2BQE08V%2BeT4iJJcj3ov_V4nsuxPfSFQ@mail.gmail.com> References: <CALH631mtKV=0z0Pj83GZ%2BQE08V%2BeT4iJJcj3ov_V4nsuxPfSFQ@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
Hi, > On 4 Jun 2025, at 09:04, Gleb Popov <arrowd@FreeBSD.org> wrote: > > Hey hackers. > > I was debugging two seemingly unrelated issues regarding busy-looping > in D-Bus and Qt applications and bumped into a common root problem - > our poll() implementation doesn't return POLLERR when callers expect > that. The standard is indeed blurry on this topic [1] and does not > specify when exactly POLLERR should be delivered. Well strictly the only thing that is unclear in the standard is whether it’s OK to return POLLERR with POLLHUP. > Here is a program that demonstrates the difference: https://arrowd.name/poll.c > On Linux I only see > > 28 (POLLOUT | POLLERR | POLLHUP) > 28 (POLLOUT | POLLERR | POLLHUP) > ... > > and on FreeBSD I get > > 20 (POLLOUT|POLLWRNORM|POLLHUP) > 16 (POLLHUP) > 16 (POLLHUP) > ... > > Now here are places in the code expecting POLLERR: > - Qt [2] + [3], [4] > - D-Bus [5] > > On FreeBSD these places result in busy-loop, because poll() returns > immediately, but the caller code does not handle the revents = POLLHUP > case properly and gets back to calling poll() again. > > My question is what would be a correct way to fix these issues. Should > I patch poll() consumers to better handle POLLHUP or should we rather > fix the kernel side to return POLLERR? Consumers looking for disconnexion should test POLLHUP not POLLERR. > Grepping through the src reveals that we have places, where calling > code requests POLLERR in .events, which makes me think that it is the > kernel that should be fixed. But I'm not a real kernel hacker. > > P.S. Interestingly, the standard says that POLLOUT and POLLHUP are > mutually exclusive, but both Linux and FreeBSD send them together. ... which is clearly a bug; but consumers ought to ignore POLLOUT if they see POLLHUP. > [1] https://pubs.opengroup.org/onlinepubs/009696799/functions/poll.html > [2] https://github.com/qt/qtbase/blob/4db3961ee140867e14f8e1d20173e85060bc6c50/src/corelib/kernel/qeventdispatcher_glib.cpp#L60 > [3] https://github.com/qt/qtbase/blob/4db3961ee140867e14f8e1d20173e85060bc6c50/src/corelib/kernel/qeventdispatcher_glib.cpp#L437 > [4] https://github.com/qt/qtbase/blob/4db3961ee140867e14f8e1d20173e85060bc6c50/src/network/socket/qnativesocketengine_unix.cpp#L1383 > [5] https://gitlab.freedesktop.org/dbus/dbus/-/blob/6bba6c58c5635bc123cb565ee1aac0f12cd980d3/dbus/dbus-transport-socket.c?page=2#L1207-1212 > -- Bob Bishop rb@gid.co.uk
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?B9BBB7F3-6984-4180-85D1-D5298A278F13>
