]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: task: provide 3 task_new_* wrappers to simplify the API
authorWilly Tarreau <w@1wt.eu>
Fri, 1 Oct 2021 16:23:30 +0000 (18:23 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 1 Oct 2021 16:36:29 +0000 (18:36 +0200)
We'll need to improve the API to pass other arguments in the future, so
let's start to adapt better to the current use cases. task_new() is used:
  - 18 times as task_new(tid_bit)
  - 18 times as task_new(MAX_THREADS_MASK)
  - 2 times with a single bit (in a loop)
  - 1 in the debug code that uses a mask

This patch provides 3 new functions to achieve this:
  - task_new_here()     to create a task on the calling thread
  - task_new_anywhere() to create a task to be run anywhere
  - task_new_on()       to create a task to run on a specific thread

The change is trivial and will allow us to later concentrate the
required adaptations to these 3 functions only. It's still possible
to call task_new() if needed but a comment was added to encourage the
use of the new ones instead. The debug code was not changed and still
uses it.

23 files changed:
include/haproxy/applet.h
include/haproxy/task.h
src/cfgparse.c
src/check.c
src/connection.c
src/dns.c
src/flt_spoe.c
src/hlua.c
src/listener.c
src/mailers.c
src/mux_fcgi.c
src/mux_h1.c
src/mux_h2.c
src/mux_quic.c
src/peers.c
src/proxy.c
src/resolvers.c
src/server.c
src/session.c
src/sink.c
src/stick_table.c
src/stream.c
src/xprt_quic.c

index 717e017c5edfb862631d36b6c29c14ec104861ea..97b9c347b4fe55530a2c92d46ccf0f6b31a51484 100644 (file)
@@ -68,7 +68,7 @@ static inline struct appctx *appctx_new(struct applet *applet)
                appctx->obj_type = OBJ_TYPE_APPCTX;
                appctx->applet = applet;
                appctx_init(appctx);
-               appctx->t = task_new(tid_bit);
+               appctx->t = task_new_here();
                if (unlikely(appctx->t == NULL)) {
                        pool_free(pool_head_appctx, appctx);
                        return NULL;
index aa9e3b2e346ae3646ef4618bb40167f35f12f19f..7b9b4e625bf764c403b3a8178e06512a8f89990d 100644 (file)
@@ -462,8 +462,9 @@ static inline struct tasklet *tasklet_new(void)
 
 /*
  * Allocate and initialise a new task. The new task is returned, or NULL in
- * case of lack of memory. The task count is incremented. Tasks should only
- * be allocated this way, and must be freed using task_free().
+ * case of lack of memory. The task count is incremented. This API might change
+ * in the near future, so prefer one of the task_new_*() wrappers below which
+ * are usually more suitable. Tasks must be freed using task_free().
  */
 static inline struct task *task_new(unsigned long thread_mask)
 {
@@ -475,6 +476,33 @@ static inline struct task *task_new(unsigned long thread_mask)
        return t;
 }
 
+/* Allocate and initialize a new task, to run on global thread <thr>. The new
+ * task is returned, or NULL in case of lack of memory. It's up to the caller
+ * to pass a valid thread number (in tid space, 0 to nbthread-1). The task
+ * count is incremented.
+ */
+static inline struct task *task_new_on(uint thr)
+{
+       return task_new(1UL << thr);
+}
+
+/* Allocate and initialize a new task, to run on the calling thread. The new
+ * task is returned, or NULL in case of lack of memory. The task count is
+ * incremented.
+ */
+static inline struct task *task_new_here()
+{
+       return task_new(tid_bit);
+}
+
+/* Allocate and initialize a new task, to run on any thread. The new task is
+ * returned, or NULL in case of lack of memory. The task count is incremented.
+ */
+static inline struct task *task_new_anywhere()
+{
+       return task_new(MAX_THREADS_MASK);
+}
+
 /*
  * Free a task. Its context must have been freed since it will be lost. The
  * task count is decremented. It it is the current task, this one is reset.
index 250e4ed58fa2f49bb13dc5cb885fbd56bffab121..2ef62afbe1a835e02774c106401a314cc725ccdf 100644 (file)
@@ -3680,7 +3680,7 @@ out_uri_auth_compat:
                }
        }
 
-       idle_conn_task = task_new(MAX_THREADS_MASK);
+       idle_conn_task = task_new_anywhere();
        if (!idle_conn_task) {
                ha_alert("parsing : failed to allocate global idle connection task.\n");
                cfgerr++;
@@ -3690,7 +3690,7 @@ out_uri_auth_compat:
                idle_conn_task->context = NULL;
 
                for (i = 0; i < global.nbthread; i++) {
-                       idle_conns[i].cleanup_task = task_new(1UL << i);
+                       idle_conns[i].cleanup_task = task_new_on(i);
                        if (!idle_conns[i].cleanup_task) {
                                ha_alert("parsing : failed to allocate idle connection tasks for thread '%d'.\n", i);
                                cfgerr++;
@@ -3769,7 +3769,7 @@ out_uri_auth_compat:
                }
 
                /* create the task associated with the proxy */
-               curproxy->task = task_new(MAX_THREADS_MASK);
+               curproxy->task = task_new_anywhere();
                if (curproxy->task) {
                        curproxy->task->context = curproxy;
                        curproxy->task->process = manage_proxy;
index aedbed1838fa4ebb9612c90d83f89b6ceb13675f..9ac66a54592cedb1892b6034147472daaa35be2f 100644 (file)
@@ -1388,13 +1388,14 @@ int start_check_task(struct check *check, int mininter,
                            int nbcheck, int srvpos)
 {
        struct task *t;
-       unsigned long thread_mask = MAX_THREADS_MASK;
 
+       /* task for the check. Process-based checks exclusively run on thread 1. */
        if (check->type == PR_O2_EXT_CHK)
-               thread_mask = 1;
+               t = task_new_on(1);
+       else
+               t = task_new_anywhere();
 
-       /* task for the check */
-       if ((t = task_new(thread_mask)) == NULL) {
+       if (!t) {
                ha_alert("Starting [%s:%s] check: out of memory.\n",
                         check->server->proxy->id, check->server->id);
                return 0;
index bf8c60e4ff62094292292b58304e0a40dbf5ec97..a4a8a8b137380293e8fc96dd833807d545f3932a 100644 (file)
@@ -1686,7 +1686,7 @@ static struct task *mux_stopping_process(struct task *t, void *ctx, unsigned int
 static int allocate_mux_cleanup(void)
 {
        /* allocates the thread bound mux_stopping_data task */
-       mux_stopping_data[tid].task = task_new(tid_bit);
+       mux_stopping_data[tid].task = task_new_here();
        if (!mux_stopping_data[tid].task) {
                ha_alert("Failed to allocate the task for connection cleanup on thread %d.\n", tid);
                return 0;
index bc3310a9eea6200aebe6222e6ff98e0279686d12..fa6f2b907363f324403fca3d577270bdf37dcbcb 100644 (file)
--- a/src/dns.c
+++ b/src/dns.c
@@ -1027,7 +1027,7 @@ struct dns_session *dns_session_new(struct dns_stream_server *dss)
        /* never fail because it is the first watcher attached to the ring */
        DISGUISE(ring_attach(&ds->ring));
 
-       if ((ds->task_exp = task_new(tid_bit)) == NULL)
+       if ((ds->task_exp = task_new_here()) == NULL)
                goto error;
 
        ds->task_exp->process = dns_process_query_exp;
@@ -1223,7 +1223,7 @@ int dns_stream_init(struct dns_nameserver *ns, struct server *srv)
                goto out;
        }
        /* Create the task associated to the resolver target handling conns */
-       if ((dss->task_req = task_new(MAX_THREADS_MASK)) == NULL) {
+       if ((dss->task_req = task_new_anywhere()) == NULL) {
                ha_alert("memory allocation error initializing the ring for dns tcp server '%s'.\n", srv->id);
                goto out;
        }
@@ -1240,7 +1240,7 @@ int dns_stream_init(struct dns_nameserver *ns, struct server *srv)
        }
 
        /* Create the task associated to the resolver target handling conns */
-       if ((dss->task_rsp = task_new(MAX_THREADS_MASK)) == NULL) {
+       if ((dss->task_rsp = task_new_anywhere()) == NULL) {
                ha_alert("memory allocation error initializing the ring for dns tcp server '%s'.\n", srv->id);
                goto out;
        }
@@ -1250,7 +1250,7 @@ int dns_stream_init(struct dns_nameserver *ns, struct server *srv)
        dss->task_rsp->context = ns;
 
        /* Create the task associated to the resolver target handling conns */
-       if ((dss->task_idle = task_new(MAX_THREADS_MASK)) == NULL) {
+       if ((dss->task_idle = task_new_anywhere()) == NULL) {
                ha_alert("memory allocation error initializing the ring for dns tcp server '%s'.\n", srv->id);
                goto out;
        }
index 70aa8697e79f3339f90e090c429f6e14030e9b84..3262fd0cf5bceb7a16b89126e0058c4ce729e4bf 100644 (file)
@@ -1998,7 +1998,7 @@ spoe_create_appctx(struct spoe_config *conf)
                goto out_free_appctx;
 
        appctx->st0 = SPOE_APPCTX_ST_CONNECT;
-       if ((SPOE_APPCTX(appctx)->task = task_new(tid_bit)) == NULL)
+       if ((SPOE_APPCTX(appctx)->task = task_new_here()) == NULL)
                goto out_free_spoe_appctx;
 
        SPOE_APPCTX(appctx)->owner           = appctx;
index df463492b4b49b388cc11de94f35996ca5773b85..baf503b970cec5f4f28c3cd9568b555ddf5d3733 100644 (file)
@@ -8251,9 +8251,9 @@ static int hlua_register_task(lua_State *L)
         * otherwise, inherit the current thread identifier
         */
        if (state_id == 0)
-               task = task_new(MAX_THREADS_MASK);
+               task = task_new_anywhere();
        else
-               task = task_new(tid_bit);
+               task = task_new_here();
        if (!task)
                goto alloc_error;
 
@@ -8941,7 +8941,7 @@ static int hlua_applet_tcp_init(struct appctx *ctx, struct proxy *px, struct str
        ctx->ctx.hlua_apptcp.flags = 0;
 
        /* Create task used by signal to wakeup applets. */
-       task = task_new(tid_bit);
+       task = task_new_here();
        if (!task) {
                SEND_ERR(px, "Lua applet tcp '%s': out of memory.\n",
                         ctx->rule->arg.hlua_rule->fcn->name);
@@ -9134,7 +9134,7 @@ static int hlua_applet_http_init(struct appctx *ctx, struct proxy *px, struct st
                ctx->ctx.hlua_apphttp.flags |= APPLET_HTTP11;
 
        /* Create task used by signal to wakeup applets. */
-       task = task_new(tid_bit);
+       task = task_new_here();
        if (!task) {
                SEND_ERR(px, "Lua applet http '%s': out of memory.\n",
                         ctx->rule->arg.hlua_rule->fcn->name);
@@ -9753,7 +9753,7 @@ static int hlua_cli_parse_fct(char **args, char *payload, struct appctx *appctx,
         * We use the same wakeup function than the Lua applet_tcp and
         * applet_http. It is absolutely compatible.
         */
-       appctx->ctx.hlua_cli.task = task_new(tid_bit);
+       appctx->ctx.hlua_cli.task = task_new_here();
        if (!appctx->ctx.hlua_cli.task) {
                SEND_ERR(NULL, "Lua cli '%s': out of memory.\n", fcn->name);
                goto error;
index 9f408a622e35d8d60b4611f823d584511cca6add..bfe32160485b4d0bdeee2906985bd447e76c1d71 100644 (file)
@@ -1134,7 +1134,7 @@ void listener_release(struct listener *l)
 /* Initializes the listener queues. Returns 0 on success, otherwise ERR_* flags */
 static int listener_queue_init()
 {
-       global_listener_queue_task = task_new(MAX_THREADS_MASK);
+       global_listener_queue_task = task_new_anywhere();
        if (!global_listener_queue_task) {
                ha_alert("Out of memory when initializing global listener queue\n");
                return ERR_FATAL|ERR_ABORT;
index 3df02f0f55759b8340fbbea676dde62e9260e7df..3d01d7532e9907093a13f0f52b623d0b5e4522a6 100644 (file)
@@ -133,7 +133,7 @@ int init_email_alert(struct mailers *mls, struct proxy *p, char **err)
                check->addr = mailer->addr;
                check->port = get_host_port(&mailer->addr);
 
-               if ((t = task_new(MAX_THREADS_MASK)) == NULL) {
+               if ((t = task_new_anywhere()) == NULL) {
                        memprintf(err, "out of memory while allocating mailer alerts task");
                        goto error;
                }
index 3f127c78e5efc5433e9a0481234cdf3f3ca19afb..5fb1c5e1b60255987134f79d7665327c162d5cc7 100644 (file)
@@ -734,7 +734,7 @@ static int fcgi_init(struct connection *conn, struct proxy *px, struct session *
        fconn->app = app;
        fconn->task = NULL;
        if (tick_isset(fconn->timeout)) {
-               t = task_new(tid_bit);
+               t = task_new_here();
                if (!t) {
                        TRACE_ERROR("fconn task allocation failure", FCGI_EV_FCONN_NEW|FCGI_EV_FCONN_END|FCGI_EV_FCONN_ERR);
                        goto fail;
@@ -4247,7 +4247,7 @@ static int fcgi_takeover(struct connection *conn, int orig_tid)
                __ha_barrier_store();
                task_kill(task);
 
-               fcgi->task = task_new(tid_bit);
+               fcgi->task = task_new_here();
                if (!fcgi->task) {
                        fcgi_release(fcgi);
                        return -1;
index dcfa3eef0283ea7932234693fadd00b34f63ad75..5dfd26cc886bcede252f5b6cb6044b9a232851fc 100644 (file)
@@ -808,7 +808,7 @@ static int h1_init(struct connection *conn, struct proxy *proxy, struct session
                            &h1c->conn->stopping_list);
        }
        if (tick_isset(h1c->timeout)) {
-               t = task_new(tid_bit);
+               t = task_new_here();
                if (!t) {
                        TRACE_ERROR("H1C task allocation failure", H1_EV_H1C_NEW|H1_EV_H1C_END|H1_EV_H1C_ERR);
                        goto fail;
@@ -3738,7 +3738,7 @@ static int h1_takeover(struct connection *conn, int orig_tid)
                __ha_barrier_store();
                task_kill(task);
 
-               h1c->task = task_new(tid_bit);
+               h1c->task = task_new_here();
                if (!h1c->task) {
                        h1_release(h1c);
                        return -1;
index dfe0b37954110b37deae80529e4e0f448978ab82..ffdafc87614b6ad5cd8a756995e0faa6752e5ec2 100644 (file)
@@ -945,7 +945,7 @@ static int h2_init(struct connection *conn, struct proxy *prx, struct session *s
        h2c->proxy = prx;
        h2c->task = NULL;
        if (tick_isset(h2c->timeout)) {
-               t = task_new(tid_bit);
+               t = task_new_here();
                if (!t)
                        goto fail;
 
@@ -6636,7 +6636,7 @@ static int h2_takeover(struct connection *conn, int orig_tid)
                __ha_barrier_store();
                task_kill(task);
 
-               h2c->task = task_new(tid_bit);
+               h2c->task = task_new_here();
                if (!h2c->task) {
                        h2_release(h2c);
                        return -1;
index 320f612e8aa8290004b014b991cec9853bfea1f4..c4673ee86fe99a78abd949115131806f82546082 100644 (file)
@@ -602,7 +602,7 @@ static int qc_init(struct connection *conn, struct proxy *prx,
        qcc->proxy = prx;
        qcc->task = NULL;
        if (tick_isset(qcc->timeout)) {
-               t = task_new(tid_bit);
+               t = task_new_here();
                if (!t)
                        goto fail;
 
@@ -2107,7 +2107,7 @@ static int qc_takeover(struct connection *conn, int orig_tid)
                __ha_barrier_store();
                task_kill(task);
 
-               qcc->task = task_new(tid_bit);
+               qcc->task = task_new_here();
                if (!qcc->task) {
                        qc_release(qcc);
                        return -1;
index 8af74755180de28fa92f21b3deab077243d51dac..ab4d4122fcd49bb0e9d7059e0f1cb0913cfc07a9 100644 (file)
@@ -3503,7 +3503,7 @@ int peers_init_sync(struct peers *peers)
                peers->peers_fe->maxconn += 3;
        }
 
-       peers->sync_task = task_new(MAX_THREADS_MASK);
+       peers->sync_task = task_new_anywhere();
        if (!peers->sync_task)
                return 0;
 
index ad5120acf145a1908024ecbb231c01d0b3399798..db876e60d5d72f7527b64378478faba157ac53e4 100644 (file)
@@ -2039,7 +2039,7 @@ static void do_soft_stop_now()
 
        /* schedule a hard-stop after a delay if needed */
        if (tick_isset(global.hard_stop_after)) {
-               task = task_new(MAX_THREADS_MASK);
+               task = task_new_anywhere();
                if (task) {
                        task->process = hard_stop;
                        task_schedule(task, tick_add(now_ms, global.hard_stop_after));
@@ -2077,7 +2077,7 @@ void soft_stop(void)
        stopping = 1;
 
        if (tick_isset(global.grace_delay)) {
-               task = task_new(MAX_THREADS_MASK);
+               task = task_new_anywhere();
                if (task) {
                        ha_notice("Scheduling a soft-stop in %u ms.\n", global.grace_delay);
                        send_log(NULL, LOG_WARNING, "Scheduling a soft-stop in %u ms.\n", global.grace_delay);
index 3b9a246e6d06ce3333ba0336542d3942f9e0d6be..fe7b6a81edd68f869f0be964435d420dd8b3b265 100644 (file)
@@ -2412,7 +2412,7 @@ static int resolvers_finalize_config(void)
                }
 
                /* Create the task associated to the resolvers section */
-               if ((t = task_new(MAX_THREADS_MASK)) == NULL) {
+               if ((t = task_new_anywhere()) == NULL) {
                        ha_alert("resolvers '%s' : out of memory.\n", resolvers->id);
                        err_code |= (ERR_ALERT|ERR_ABORT);
                        goto err;
@@ -2453,7 +2453,7 @@ static int resolvers_finalize_config(void)
                                        }
                                }
 
-                               srv->srvrq_check = task_new(MAX_THREADS_MASK);
+                               srv->srvrq_check = task_new_anywhere();
                                if (!srv->srvrq_check) {
                                        ha_alert("%s '%s' : unable to create SRVRQ task for server '%s'.\n",
                                                 proxy_type_str(px), px->id, srv->id);
index 213d10632e69875aa995937895cd75c05de89532..b44b16469317d2b86e656f68345ae2ba9ebebe2f 100644 (file)
@@ -4480,7 +4480,7 @@ static int init_srv_slowstart(struct server *srv)
        struct task *t;
 
        if (srv->slowstart) {
-               if ((t = task_new(MAX_THREADS_MASK)) == NULL) {
+               if ((t = task_new_anywhere()) == NULL) {
                        ha_alert("Cannot activate slowstart for server %s/%s: out of memory.\n", srv->proxy->id, srv->id);
                        return ERR_ALERT | ERR_FATAL;
                }
index e3601cb4578e39f608528e195c84ae818f710f3c..d913d567df83d1c996ef519ec78c7b59698b2083 100644 (file)
@@ -248,7 +248,7 @@ int session_accept_fd(struct connection *cli_conn)
         *          conn -- owner ---> task <-----+
         */
        if (cli_conn->flags & (CO_FL_WAIT_XPRT | CO_FL_EARLY_SSL_HS)) {
-               if (unlikely((sess->task = task_new(tid_bit)) == NULL))
+               if (unlikely((sess->task = task_new_here()) == NULL))
                        goto out_free_sess;
 
                sess->task->context = sess;
index b869d2eafb3bcfe3918ca0cb1a4951081ea2e689..d694e58182a7a741c039a77570346942b4c8ff7e 100644 (file)
@@ -731,7 +731,7 @@ static struct task *process_sink_forward(struct task * task, void *context, unsi
  */
 int sink_init_forward(struct sink *sink)
 {
-       sink->forward_task = task_new(MAX_THREADS_MASK);
+       sink->forward_task = task_new_anywhere();
        if (!sink->forward_task)
                return 0;
 
index 6f07080f64a97253ba271fb17ad5e9a5d85f8e62..f5d76322c4dcf4471bf3db605d2e449c80c434d6 100644 (file)
@@ -648,7 +648,7 @@ int stktable_init(struct stktable *t)
 
                t->exp_next = TICK_ETERNITY;
                if ( t->expire ) {
-                       t->exp_task = task_new(MAX_THREADS_MASK);
+                       t->exp_task = task_new_anywhere();
                        if (!t->exp_task)
                                return 0;
                        t->exp_task->process = process_table_expire;
index 89e85d88dee3f50a1d09cf036d8c8f03b34dc170..e4d5ac9649bb4b6e2f9fc082561dab8482aca28f 100644 (file)
@@ -429,7 +429,7 @@ struct stream *stream_new(struct session *sess, enum obj_type *origin, struct bu
        s->pcli_flags = 0;
        s->unique_id = IST_NULL;
 
-       if ((t = task_new(tid_bit)) == NULL)
+       if ((t = task_new_here()) == NULL)
                goto out_fail_alloc;
 
        s->task = t;
index d1bfea8c1a83d9e84f5644c0a76de4a25b0f4575..32b8fced2dc8479ea4425d7605cd52ce6bc36db0 100644 (file)
@@ -3046,7 +3046,7 @@ static struct quic_conn *qc_new_conn(unsigned int version, int ipv4,
  */
 static int quic_conn_init_timer(struct quic_conn *qc)
 {
-       qc->timer_task = task_new(MAX_THREADS_MASK);
+       qc->timer_task = task_new_anywhere();
        if (!qc->timer_task)
                return 0;