From 43c891dda0c7c1c9f12dab5b77ac20b158a68adc Mon Sep 17 00:00:00 2001 From: William Lallemand Date: Thu, 8 Sep 2022 17:46:31 +0200 Subject: [PATCH] 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. --- src/ev_epoll.c | 6 ++++-- src/ev_evports.c | 8 ++++---- src/ev_kqueue.c | 6 ++++-- src/ev_poll.c | 7 +++++-- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/ev_epoll.c b/src/ev_epoll.c index 98ca701e19..746a0d120a 100644 --- a/src/ev_epoll.c +++ b/src/ev_epoll.c @@ -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; diff --git a/src/ev_evports.c b/src/ev_evports.c index 2530b39c04..7d3e8a8d77 100644 --- a/src/ev_evports.c +++ b/src/ev_evports.c @@ -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 { diff --git a/src/ev_kqueue.c b/src/ev_kqueue.c index 3c8787ffd7..1d6e91d506 100644 --- a/src/ev_kqueue.c +++ b/src/ev_kqueue.c @@ -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(); diff --git a/src/ev_poll.c b/src/ev_poll.c index 790ea5bfaf..6fefb3ab3f 100644 --- a/src/ev_poll.c +++ b/src/ev_poll.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -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); -- 2.39.5