Re: Behavioral difference between Linux and FreeBSD poll()
- In reply to: Gleb Popov : "Behavioral difference between Linux and FreeBSD poll()"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 04 Jun 2025 11:49:44 UTC
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