diff options
| author | Gleb Popov <[email protected]> | 2025-06-08 17:25:40 +0300 |
|---|---|---|
| committer | Gleb Popov <[email protected]> | 2025-06-12 15:20:49 +0300 |
| commit | 4ba106b38fe94ae3a7a8520b276a4873d11bb755 (patch) | |
| tree | 13a0b3490a78bdbc1ae6a59a11d349feaae6d49e /src | |
| parent | 5b86fca7cf21c79a1ec94dc242290ae23101b67c (diff) | |
QEventDispatcherGlib: Put G_IO_HUP into pfd.events for all cases of QSocketNotifier::Type
On FreeBSD when asked for POLLOUT the poll() syscall returns only POLLHUP to
signify the fact that the other side closed the connection. It never sends
POLLERR for EOF cases, which results in a busy-loop inside the Glib dispatcher:
- poll() returns immediately with POLLHUP for a closed socket
- socketNotifierSourceCheck() does not detect it, because .events = POLLOUT | POLLERR
and we get .revents = POLLHUP. The (events & revents != 0) condition evaluates to false
- the code decides there is nothing to do and a new iteration starts
A similar issue in dbus code: https://gitlab.freedesktop.org/dbus/dbus/-/merge_requests/526
Change-Id: I2660a5179031da8eb9fe2562abe7fb283c77f64a
Reviewed-by: Thiago Macieira <[email protected]>
Diffstat (limited to 'src')
| -rw-r--r-- | src/corelib/kernel/qeventdispatcher_glib.cpp | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_glib.cpp b/src/corelib/kernel/qeventdispatcher_glib.cpp index a564c49cd51..921da3784ea 100644 --- a/src/corelib/kernel/qeventdispatcher_glib.cpp +++ b/src/corelib/kernel/qeventdispatcher_glib.cpp @@ -434,10 +434,10 @@ void QEventDispatcherGlib::registerSocketNotifier(QSocketNotifier *notifier) p->pollfd.events = G_IO_IN | G_IO_HUP | G_IO_ERR; break; case QSocketNotifier::Write: - p->pollfd.events = G_IO_OUT | G_IO_ERR; + p->pollfd.events = G_IO_OUT | G_IO_HUP | G_IO_ERR; break; case QSocketNotifier::Exception: - p->pollfd.events = G_IO_PRI | G_IO_ERR; + p->pollfd.events = G_IO_PRI | G_IO_HUP | G_IO_ERR; break; } p->socketNotifier = notifier; |
