MINOR: listener: workaround for closing a tiny race between resume_listener() and stopping

This is an alternative fix that tries to address the same issue as
d1ebee177 ("BUG/MINOR: listener: close tiny race between
resume_listener() and stopping") while allowing resume_listener() to be
more versatile.

Indeed, because of the previous fix, resume_listener() is not able to
rebind stopped listeners, and this breaks the original behavior that is
documented in the function description:

 "If the listener was only in the assigned
  state, it's totally rebound. This can happen if a pause() has completely
  stopped it. If the resume fails, 0 is returned and an error might be
  displayed."

With relax_listener(), we now make sure to check l->state under the
listener lock so we don't call resume_listener() when the conditions are not
met.

As such, concurrently stopped listeners may not be rebound using
relax_listener().

Note: the documented race can't happen since 1b927eb3c ("MEDIUM: proto: stop
protocols under thread isolation during soft stop"), but older versions are
concerned as 1b927eb3c was not marked for backports.
Moreover, the patch also prevents the race between protocol_pause_all() and
resuming from LIMITED or FULL states.

This commit depends on:
  - "MINOR: listener: add relax_listener() function"

This should be backported with d1ebee177 up to 2.4
(d1ebee177 is marked to be backported for all stable versions but the current
patch does not apply for versions < 2.4)

(cherry picked from commit f5d98938ad0edf85ae4d10a6d6c088915c1faaed)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 3353ccc853dcfd547d5cdd7561a2af24eaad9887)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit c2d190000824da34deafcdc82a7ef3c495752b10)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit b84a6bb601180104659179b03f1ba107c6633aee)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
2 files changed