]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: signals/poller: set the poller timeout to 0 when there are signals
authorWilliam Lallemand <wlallemand@haproxy.org>
Thu, 8 Sep 2022 15:46:31 +0000 (17:46 +0200)
committerWilliam Lallemand <wlallemand@haproxy.org>
Thu, 8 Sep 2022 15:46:31 +0000 (17:46 +0200)
When receiving a signal before entering the poller, and without any
activity in the process, the poller will be entered with a timeout
calculated without checking the signals.

Since commit 4f59d3 ("MINOR: time: increase the minimum wakeup interval
to 60s") the issue is much more visible because it could be stuck for
60s.

When in mworker mode, if a worker quits and the SIGCHLD signal deliver
at the right time to the master, this one could be stuck for the time of
the timeout.

This should fix issue #1841

Must be backported in every stable version.

src/ev_epoll.c
src/ev_evports.c
src/ev_kqueue.c
src/ev_poll.c

index 98ca701e19ef670eca3e21ef8b899aadf28f0254..746a0d120af24685fc15b1e3eb19cf633218ff9a 100644 (file)
@@ -222,8 +222,10 @@ static void _do_poll(struct poller *p, int exp, int wake)
        thread_idle_now();
        thread_harmless_now();
 
-       /* now let's wait for polled events */
-       wait_time = wake ? 0 : compute_poll_timeout(exp);
+       /* Now let's wait for polled events.
+        * Check if the signal queue is not empty in case we received a signal
+        * before entering the loop, so we don't wait MAX_DELAY_MS for nothing */
+       wait_time = (wake | signal_queue_len) ? 0 : compute_poll_timeout(exp);
        clock_entering_poll();
        do {
                int timeout = (global.tune.options & GTUNE_BUSY_POLLING) ? 0 : wait_time;
index 2530b39c046d25bef28f89975c5bfc35b03b5a6a..7d3e8a8d77cb8ed5b934b3467cf09bc5ce2884ef 100644 (file)
@@ -178,10 +178,10 @@ static void _do_poll(struct poller *p, int exp, int wake)
        thread_idle_now();
        thread_harmless_now();
 
-       /*
-        * Determine how long to wait for events to materialise on the port.
-        */
-       wait_time = wake ? 0 : compute_poll_timeout(exp);
+       /* Now let's wait for polled events.
+        * Check if the signal queue is not empty in case we received a signal
+        * before entering the loop, so we don't wait MAX_DELAY_MS for nothing */
+       wait_time = (wake | signal_queue_len) ? 0 : compute_poll_timeout(exp);
        clock_entering_poll();
 
        do {
index 3c8787ffd780adea59a01914c2ebf5668f412f3b..1d6e91d5066331de47599d4db74ee677ebf8f98e 100644 (file)
@@ -166,8 +166,10 @@ static void _do_poll(struct poller *p, int exp, int wake)
        }
        fd_nbupdt = 0;
 
-       /* now let's wait for events */
-       wait_time = wake ? 0 : compute_poll_timeout(exp);
+       /* Now let's wait for polled events.
+        * Check if the signal queue is not empty in case we received a signal
+        * before entering the loop, so we don't wait MAX_DELAY_MS for nothing */
+       wait_time = (wake | signal_queue_len) ? 0 : compute_poll_timeout(exp);
        fd = global.tune.maxpollevents;
        clock_entering_poll();
 
index 790ea5bfaf8ee73009ee5cd4eb42072b16e2e372..6fefb3ab3fcb97c28f4ff3b203ff672b0692f8ed 100644 (file)
@@ -22,6 +22,7 @@
 #include <haproxy/clock.h>
 #include <haproxy/fd.h>
 #include <haproxy/global.h>
+#include <haproxy/signal.h>
 #include <haproxy/task.h>
 #include <haproxy/ticks.h>
 
@@ -203,8 +204,10 @@ static void _do_poll(struct poller *p, int exp, int wake)
                }
        }
 
-       /* now let's wait for events */
-       wait_time = wake ? 0 : compute_poll_timeout(exp);
+       /* Now let's wait for polled events.
+        * Check if the signal queue is not empty in case we received a signal
+        * before entering the loop, so we don't wait MAX_DELAY_MS for nothing */
+       wait_time = (wake | signal_queue_len) ? 0 : compute_poll_timeout(exp);
        clock_entering_poll();
        status = poll(poll_events, nbfd, wait_time);
        clock_update_date(wait_time, status);