]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: listener: split dequeue_all_listener() in two
authorWilly Tarreau <w@1wt.eu>
Tue, 10 Dec 2019 13:10:52 +0000 (14:10 +0100)
committerWilly Tarreau <w@1wt.eu>
Tue, 10 Dec 2019 13:14:09 +0000 (14:14 +0100)
We use it half times for the global_listener_queue and half times
for a proxy's queue and this requires the callers to take care of
these. Let's split it in two versions, the current one working only
on the global queue and another one dedicated to proxies for the
per-proxy queues. This cleans up quite a bit of code.

include/proto/listener.h
src/cli.c
src/haproxy.c
src/listener.c
src/proxy.c

index 2336e63462f3c0a5e31c4c19cb682fbb0d855e3e..e8f9ece5f44419b6b4a96168e0a5d4fe5a20b762 100644 (file)
@@ -57,8 +57,11 @@ int enable_all_listeners(struct protocol *proto);
  */
 int disable_all_listeners(struct protocol *proto);
 
-/* Dequeues all of the listeners waiting for a resource in wait queue <queue>. */
-void dequeue_all_listeners(struct mt_list *list);
+/* Dequeues all listeners waiting for a resource the global wait queue */
+void dequeue_all_listeners();
+
+/* Dequeues all listeners waiting for a resource in proxy <px>'s queue */
+void dequeue_proxy_listeners(struct proxy *px);
 
 /* Must be called with the lock held. Depending on <do_close> value, it does
  * what unbind_listener or unbind_listener_no_close should do.
index 77db8be883259b2845afa3b09f5d779b79398ee4..ba48d147265f94aafdd0d52c2c26ff71c8f156d4 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -1391,8 +1391,7 @@ static int cli_parse_set_maxconn_global(char **args, char *payload, struct appct
        global.maxconn = v;
 
        /* Dequeues all of the listeners waiting for a resource */
-       if (!MT_LIST_ISEMPTY(&global_listener_queue))
-               dequeue_all_listeners(&global_listener_queue);
+       dequeue_all_listeners();
 
        return 1;
 }
@@ -1529,8 +1528,7 @@ static int cli_parse_set_ratelimit(char **args, char *payload, struct appctx *ap
        *res = v * mul;
 
        /* Dequeues all of the listeners waiting for a resource */
-       if (!MT_LIST_ISEMPTY(&global_listener_queue))
-               dequeue_all_listeners(&global_listener_queue);
+       dequeue_all_listeners();
 
        return 1;
 }
index b6e59dcf356ab746f6e6b70f1781870f453dc410..c8b59654eafd4eb83a754967b462fc5c3dc52026 100644 (file)
@@ -2807,11 +2807,6 @@ static void *run_thread_poll_loop(void *data)
  */
 static struct task *manage_global_listener_queue(struct task *t, void *context, unsigned short state)
 {
-       int next = TICK_ETERNITY;
-       /* queue is empty, nothing to do */
-       if (MT_LIST_ISEMPTY(&global_listener_queue))
-               goto out;
-
        /* If there are still too many concurrent connections, let's wait for
         * some of them to go away. We don't need to re-arm the timer because
         * each of them will scan the queue anyway.
@@ -2825,10 +2820,10 @@ static struct task *manage_global_listener_queue(struct task *t, void *context,
         * as a file descriptor or memory and that the temporary condition has
         * disappeared.
         */
-       dequeue_all_listeners(&global_listener_queue);
+       dequeue_all_listeners();
 
  out:
-       t->expire = next;
+       t->expire = TICK_ETERNITY;
        task_queue(t);
        return t;
 }
index 49af4fd984491b1851649499012666622a798f1b..848b01eaeeede33dc455a9135148313d76c6a8a0 100644 (file)
@@ -463,12 +463,25 @@ int disable_all_listeners(struct protocol *proto)
        return ERR_NONE;
 }
 
-/* Dequeues all of the listeners waiting for a resource in wait queue <queue>. */
-void dequeue_all_listeners(struct mt_list *list)
+/* Dequeues all listeners waiting for a resource the global wait queue */
+void dequeue_all_listeners()
 {
        struct listener *listener;
 
-       while ((listener = MT_LIST_POP(list, struct listener *, wait_queue))) {
+       while ((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.
+                */
+               resume_listener(listener);
+       }
+}
+
+/* Dequeues all listeners waiting for a resource in proxy <px>'s queue */
+void dequeue_proxy_listeners(struct proxy *px)
+{
+       struct listener *listener;
+
+       while ((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.
                 */
@@ -1036,12 +1049,11 @@ void listener_accept(int fd)
                resume_listener(l);
 
                /* Dequeues all of the listeners waiting for a resource */
-               if (!MT_LIST_ISEMPTY(&global_listener_queue))
-                       dequeue_all_listeners(&global_listener_queue);
+               dequeue_all_listeners();
 
                if (p && !MT_LIST_ISEMPTY(&p->listener_queue) &&
                    (!p->fe_sps_lim || freq_ctr_remain(&p->fe_sess_per_sec, p->fe_sps_lim, 0) > 0))
-                       dequeue_all_listeners(&p->listener_queue);
+                       dequeue_proxy_listeners(p);
        }
 
        /* Now it's getting tricky. The listener was supposed to be in LI_READY
@@ -1104,12 +1116,11 @@ void listener_release(struct listener *l)
                resume_listener(l);
 
        /* Dequeues all of the listeners waiting for a resource */
-       if (!MT_LIST_ISEMPTY(&global_listener_queue))
-               dequeue_all_listeners(&global_listener_queue);
+       dequeue_all_listeners();
 
        if (!MT_LIST_ISEMPTY(&fe->listener_queue) &&
            (!fe->fe_sps_lim || freq_ctr_remain(&fe->fe_sess_per_sec, fe->fe_sps_lim, 0) > 0))
-               dequeue_all_listeners(&fe->listener_queue);
+               dequeue_proxy_listeners(fe);
 }
 
 /* resume listeners waiting in the local listener queue. They are still in LI_LIMITED state */
index 1724766234ce7dbc23c090c474bd2f97104cc3af..838722d1e18dc20862b0e1abe4619eae2b678d8b 100644 (file)
@@ -1034,8 +1034,7 @@ struct task *manage_proxy(struct task *t, void *context, unsigned short state)
        }
 
        /* The proxy is not limited so we can re-enable any waiting listener */
-       if (!MT_LIST_ISEMPTY(&p->listener_queue))
-               dequeue_all_listeners(&p->listener_queue);
+       dequeue_proxy_listeners(p);
  out:
        t->expire = next;
        task_queue(t);
@@ -2037,8 +2036,8 @@ static int cli_parse_set_maxconn_frontend(char **args, char *payload, struct app
                        resume_listener(l);
        }
 
-       if (px->maxconn > px->feconn && !MT_LIST_ISEMPTY(&px->listener_queue))
-               dequeue_all_listeners(&px->listener_queue);
+       if (px->maxconn > px->feconn)
+               dequeue_proxy_listeners(px);
 
        HA_SPIN_UNLOCK(PROXY_LOCK, &px->lock);