BUG/MINOR: signals/poller: set the poller timeout to 0 when there are signals

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.
This commit is contained in:
William Lallemand 2022-09-08 17:46:31 +02:00
parent e86bc35672
commit 43c891dda0
4 changed files with 17 additions and 10 deletions

View 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;

View 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 {

View 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();

View 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);