When dequeueing listeners in dequeue_all_listeners() and
dequeue_proxy_listeners(), consider if we reached maxconn before doing
so.
If we do not, with enough thread groups, we may enter a state in which we
dequeue listeners, try again to accept more connections, but that would
fail, as maxconn would have been reached again by a different thread
group, and we'd end up being stuck for long enough for the watchdog to
trigger.
This should be backported up to 2.8.
This was submitted by Bruno Henc in github issue #3525.
{
struct listener *listener;
- while ((listener = MT_LIST_POP(&global_listener_queue, struct listener *, wait_queue))) {
+ while (_HA_ATOMIC_LOAD(&actconn) < global.maxconn &&
+ (listener = MT_LIST_POP(&global_listener_queue, struct listener *, wait_queue))) {
/* This cannot fail because the listeners are by definition in
* the LI_LIMITED state.
*/
{
struct listener *listener;
- while ((listener = MT_LIST_POP(&px->listener_queue, struct listener *, wait_queue))) {
+ while (_HA_ATOMIC_LOAD(&px->feconn) < px->maxconn &&
+ (listener = MT_LIST_POP(&px->listener_queue, struct listener *, wait_queue))) {
/* This cannot fail because the listeners are by definition in
* the LI_LIMITED state.
*/