Skip to content

Commit

Permalink
MINOR: listener: add relax_listener() function
Browse files Browse the repository at this point in the history
There is a need for a small difference between resuming and relaxing
a listener.

When resuming, we expect that the listener may completely resume, this includes
unpausing or rebinding if required.
Resuming a listener is a best-effort operation: no matter the current state,
try our best to bring the listener up to the LI_READY state.

There are some cases where we only want to "relax" listeners that were
previously restricted using limit_listener() or listener_full() functions.
Here we don't want to ressucitate listeners, we're simply interested in
cancelling out the previous restriction.

To this day, listener_resume() on a unbound listener is broken, that's why
the need for this wasn't felt yet.

But we're trying to restore historical listener_resume() behavior, so we better
prepare for this by introducing an explicit relax_listener() function that
only does what is expected in such cases.

This commit depends on:
 - "MINOR: listener/api: add lli hint to listener functions"

(cherry picked from commit bcad7e6)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit d170427)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
  • Loading branch information
Darlelet authored and capflam committed Apr 21, 2023
1 parent 46522dd commit 9bfa34f
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 0 deletions.
12 changes: 12 additions & 0 deletions include/haproxy/listener.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@ int pause_listener(struct listener *l, int lpx, int lli);
*/
int resume_listener(struct listener *l, int lpx, int lli);

/* Same as resume_listener(), but will only work to resume from
* LI_FULL or LI_LIMITED states because we try to relax listeners that
* were temporarily restricted and not to resume inactive listeners that
* may have been paused or completely stopped in the meantime.
* Returns positive value for success and 0 for failure.
* It will need to operate under the proxy's lock and the listener's lock.
* The caller is responsible for indicating in lpx, lli whether the respective
* locks are already held (non-zero) or not (zero) so that the function pick
* the missing ones, in this order.
*/
int relax_listener(struct listener *l, int lpx, int lli);

/*
* This function completely stops a listener. It will need to operate under the
* proxy's lock, the protocol's and the listener's lock. The caller is
Expand Down
27 changes: 27 additions & 0 deletions src/listener.c
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,33 @@ int resume_listener(struct listener *l, int lpx, int lli)
return ret;
}

/* Same as resume_listener(), but will only work to resume from
* LI_FULL or LI_LIMITED states because we try to relax listeners that
* were temporarily restricted and not to resume inactive listeners that
* may have been paused or completely stopped in the meantime.
* Returns positive value for success and 0 for failure.
* It will need to operate under the proxy's lock and the listener's lock.
* The caller is responsible for indicating in lpx, lli whether the respective
* locks are already held (non-zero) or not (zero) so that the function pick
* the missing ones, in this order.
*/
int relax_listener(struct listener *l, int lpx, int lli)
{
int ret = 1;

if (!lli)
HA_RWLOCK_WRLOCK(LISTENER_LOCK, &l->lock);

if (l->state != LI_FULL && l->state != LI_LIMITED)
goto end; /* listener may be suspended or even stopped */
ret = resume_listener(l, lpx, 1);

end:
if (!lli)
HA_RWLOCK_WRUNLOCK(LISTENER_LOCK, &l->lock);
return ret;
}

/* Marks a ready listener as full so that the stream code tries to re-enable
* it upon next close() using resume_listener().
*/
Expand Down

0 comments on commit 9bfa34f

Please sign in to comment.