From: Petr Malat Date: Wed, 4 Dec 2024 09:30:24 +0000 (+0100) Subject: _dbus_loop_iterate: Fix OOM retry timeout handling X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a6023f49acfda099a7ccac9ebd804d553ec9d666;p=thirdparty%2Fdbus.git _dbus_loop_iterate: Fix OOM retry timeout handling If there is a pending OOM watch and at the same time there is no timeout, poll is entered with infinite timeout, because infinite is expressed with a negative number, which is smaller than any actual timeout. Introduce min_poll_timeout(), which returns the smaller non-negative number of the two, or the larger negative number if both numbers are negative. Resolves: https://gitlab.freedesktop.org/dbus/dbus/-/issues/536 Signed-off-by: Petr Malat [smcv: adjust whitespace] Signed-off-by: Simon McVittie --- diff --git a/dbus/dbus-mainloop.c b/dbus/dbus-mainloop.c index 91030e394..4de5a7ae9 100644 --- a/dbus/dbus-mainloop.c +++ b/dbus/dbus-mainloop.c @@ -562,6 +562,20 @@ _dbus_loop_queue_dispatch (DBusLoop *loop, return FALSE; } +/* Returns the smaller non-negative number of the two, or the larger negative + * number if both numbers are negative. Poll interprets negative timeout as + * infinity, which makes it longer than any actual timeout. + */ +static int +min_poll_timeout (int a, + int b) +{ + if (a < b) + return a < 0 ? b : a; + else + return b < 0 ? a : b; +} + /* Returns TRUE if we invoked any timeouts or have ready file * descriptors, which is just used in test code as a debug hack */ @@ -620,10 +634,7 @@ _dbus_loop_iterate (DBusLoop *loop, check_timeout (tv_sec, tv_usec, tcb, &msecs_remaining); - if (timeout < 0) - timeout = msecs_remaining; - else - timeout = MIN (msecs_remaining, timeout); + timeout = min_poll_timeout (msecs_remaining, timeout); #if MAINLOOP_SPEW _dbus_verbose (" timeout added, %d remaining, aggregate timeout %ld\n", @@ -656,7 +667,7 @@ _dbus_loop_iterate (DBusLoop *loop, * wait to re-enable it */ if (loop->oom_watch_pending) - timeout = MIN (timeout, _dbus_get_oom_wait ()); + timeout = min_poll_timeout (timeout, _dbus_get_oom_wait ()); #if MAINLOOP_SPEW _dbus_verbose (" polling on %d descriptors timeout %ld\n", _DBUS_N_ELEMENTS (ready_fds), timeout);