summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilly Tarreau <w@1wt.eu>2020-09-25 20:32:28 +0200
committerWilly Tarreau <w@1wt.eu>2020-10-07 19:40:33 +0200
commit25f70ecdf0aff4e7ab1a4869f1f8a01666b57de3 (patch)
treecda599233d9d9e0a34a2a1965a5e59bf1fa0b8d2
parentd1b13e776c41c0bb800e2cbb641a2f422de76544 (diff)
downloadhaproxy-25f70ecdf0aff4e7ab1a4869f1f8a01666b57de3.tar.gz
MEDIUM: listeners: now use the listener's ->enable/disable
At each place we used to manipulate the FDs directly we can now call the listener protocol's enable/disable/rx_enable/rx_disable depending on whether the state changes on the listener or the receiver. One exception currently remains in listener_accept() which is a bit special and which should be split into 2 or 3 parts in the various protocol layers. The test of fd_updt in do_unbind_listener() that was added by commit a51885621 ("BUG/MEDIUM: listeners: Don't call fd_stop_recv() if fd_updt is NULL.") could finally be removed since that part is correctly handled in the low-level disable() function. One disable() was added in resume_listener() before switching to LI_FULL because rx_resume() enables polling on the FD for the receiver while we want to disable it if the listener is full. There are different ways to clean this up in the future. One of them could be to consider that TCP receivers only act at the listener level. But in fact it does not translate reality. The reality is that only the receiver is paused and that the listener's state ought not be affected here. Ultimately the resume_listener() function should be split so that the part controlled by the protocols only acts on the receiver, and that the receiver itself notifies the upper listener about the change so that the listener protocol may decide to disable or enable polling. Conversely the listener should automatically update its receiver when they share the same state. Since there is no harm proceeding like this, let's keep this for now.
-rw-r--r--src/listener.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/src/listener.c b/src/listener.c
index e0a08b262..9b43485e4 100644
--- a/src/listener.c
+++ b/src/listener.c
@@ -293,7 +293,7 @@ void enable_listener(struct listener *listener)
}
}
else if (!listener->maxconn || listener->nbconn < listener->maxconn) {
- fd_want_recv(listener->rx.fd);
+ listener->rx.proto->enable(listener);
listener_set_state(listener, LI_READY);
}
else {
@@ -415,11 +415,12 @@ int resume_listener(struct listener *l)
}
if (l->maxconn && l->nbconn >= l->maxconn) {
+ l->rx.proto->disable(l);
listener_set_state(l, LI_FULL);
goto done;
}
- fd_want_recv(l->rx.fd);
+ l->rx.proto->enable(l);
listener_set_state(l, LI_READY);
done:
@@ -441,7 +442,7 @@ static void listener_full(struct listener *l)
if (l->state >= LI_READY) {
MT_LIST_DEL(&l->wait_queue);
if (l->state != LI_FULL) {
- fd_stop_recv(l->rx.fd);
+ l->rx.proto->disable(l);
listener_set_state(l, LI_FULL);
}
}
@@ -456,7 +457,7 @@ static void limit_listener(struct listener *l, struct mt_list *list)
HA_SPIN_LOCK(LISTENER_LOCK, &l->lock);
if (l->state == LI_READY) {
MT_LIST_TRY_ADDQ(list, &l->wait_queue);
- fd_stop_recv(l->rx.fd);
+ l->rx.proto->disable(l);
listener_set_state(l, LI_LIMITED);
}
HA_SPIN_UNLOCK(LISTENER_LOCK, &l->lock);
@@ -494,14 +495,14 @@ void dequeue_proxy_listeners(struct proxy *px)
*/
void do_unbind_listener(struct listener *listener, int do_close)
{
- if (listener->state == LI_READY && fd_updt)
- fd_stop_recv(listener->rx.fd);
+ if (listener->state == LI_READY)
+ listener->rx.proto->disable(listener);
MT_LIST_DEL(&listener->wait_queue);
if (listener->state >= LI_PAUSED) {
listener_set_state(listener, LI_ASSIGNED);
- fd_stop_both(listener->rx.fd);
+ listener->rx.proto->rx_disable(&listener->rx);
}
if (do_close && listener->rx.fd != -1) {