From 69ebc3093a4b99f10dee95c0e5f44ecedb9bbf5c Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Thu, 12 May 2022 15:28:51 +0200 Subject: [PATCH] MEDIUM: spoe: Refactor SPOE appctx creation A .init callback function is defined for the spoe_applet applet. This function finishes the spoe_appctx initialization. It also finishes the appctx startup by calling appctx_finalize_startup() and its handles the stream customization. --- src/flt_spoe.c | 124 +++++++++++++++++++++++++++---------------------- 1 file changed, 68 insertions(+), 56 deletions(-) diff --git a/src/flt_spoe.c b/src/flt_spoe.c index c176a9b41..99ef7d6fd 100644 --- a/src/flt_spoe.c +++ b/src/flt_spoe.c @@ -1214,6 +1214,52 @@ spoe_process_appctx(struct task * task, void *context, unsigned int state) return task; } +static int +spoe_init_appctx(struct appctx *appctx) +{ + struct spoe_appctx *spoe_appctx = SPOE_APPCTX(appctx); + struct spoe_agent *agent = spoe_appctx->agent; + struct task *task; + struct stream *s; + + if ((task = task_new_here()) == NULL) + goto out_free_task; + task->process = spoe_process_appctx; + task->context = appctx; + + if (appctx_finalize_startup(appctx, &agent->spoe_conf->agent_fe, &BUF_NULL) == -1) + goto out_error; + + spoe_appctx->owner = appctx; + spoe_appctx->task = task; + + LIST_INIT(&spoe_appctx->buffer_wait.list); + spoe_appctx->buffer_wait.target = appctx; + spoe_appctx->buffer_wait.wakeup_cb = (int (*)(void *))spoe_wakeup_appctx; + + s = appctx_strm(appctx); + stream_set_backend(s, agent->b.be); + + /* applet is waiting for data */ + cs_cant_get(s->csf); + + s->do_log = NULL; + s->res.flags |= CF_READ_DONTWAIT; + + HA_SPIN_LOCK(SPOE_APPLET_LOCK, &agent->rt[tid].lock); + LIST_APPEND(&agent->rt[tid].applets, &spoe_appctx->list); + HA_SPIN_UNLOCK(SPOE_APPLET_LOCK, &agent->rt[tid].lock); + _HA_ATOMIC_INC(&agent->counters.applets); + + appctx->st0 = SPOE_APPCTX_ST_CONNECT; + task_wakeup(spoe_appctx->task, TASK_WOKEN_INIT); + return 0; + out_free_task: + task_destroy(task); + out_error: + return -1; +} + /* Callback function that releases a SPOE applet. This happens when the * connection with the agent is closed. */ static void @@ -1980,6 +2026,7 @@ struct applet spoe_applet = { .obj_type = OBJ_TYPE_APPLET, .name = "", /* used for logging */ .fct = spoe_handle_appctx, + .init = spoe_init_appctx, .release = spoe_release_appctx, }; @@ -1988,74 +2035,39 @@ struct applet spoe_applet = { static struct appctx * spoe_create_appctx(struct spoe_config *conf) { - struct appctx *appctx; - struct session *sess; - struct conn_stream *cs; - struct stream *strm; + struct spoe_appctx *spoe_appctx; + struct appctx *appctx; - if ((appctx = appctx_new(&spoe_applet, NULL)) == NULL) + spoe_appctx = pool_zalloc(pool_head_spoe_appctx); + if (spoe_appctx == NULL) goto out_error; - appctx->svcctx = pool_zalloc(pool_head_spoe_appctx); - if (SPOE_APPCTX(appctx) == NULL) - goto out_free_appctx; + spoe_appctx->agent = conf->agent; + spoe_appctx->version = 0; + spoe_appctx->max_frame_size = conf->agent->max_frame_size; + spoe_appctx->flags = 0; + spoe_appctx->status_code = SPOE_FRM_ERR_NONE; + spoe_appctx->buffer = BUF_NULL; + spoe_appctx->cur_fpa = 0; + LIST_INIT(&spoe_appctx->list); + LIST_INIT(&spoe_appctx->waiting_queue); - appctx->st0 = SPOE_APPCTX_ST_CONNECT; - if ((SPOE_APPCTX(appctx)->task = task_new_here()) == NULL) + + if ((appctx = appctx_new(&spoe_applet, NULL)) == NULL) goto out_free_spoe_appctx; - SPOE_APPCTX(appctx)->owner = appctx; - SPOE_APPCTX(appctx)->task->process = spoe_process_appctx; - SPOE_APPCTX(appctx)->task->context = appctx; - SPOE_APPCTX(appctx)->agent = conf->agent; - SPOE_APPCTX(appctx)->version = 0; - SPOE_APPCTX(appctx)->max_frame_size = conf->agent->max_frame_size; - SPOE_APPCTX(appctx)->flags = 0; - SPOE_APPCTX(appctx)->status_code = SPOE_FRM_ERR_NONE; - SPOE_APPCTX(appctx)->buffer = BUF_NULL; - SPOE_APPCTX(appctx)->cur_fpa = 0; + appctx->svcctx = spoe_appctx; + if (appctx_init(appctx) == -1) + goto out_free_appctx; - LIST_INIT(&SPOE_APPCTX(appctx)->buffer_wait.list); - SPOE_APPCTX(appctx)->buffer_wait.target = appctx; - SPOE_APPCTX(appctx)->buffer_wait.wakeup_cb = (int (*)(void *))spoe_wakeup_appctx; - - LIST_INIT(&SPOE_APPCTX(appctx)->list); - LIST_INIT(&SPOE_APPCTX(appctx)->waiting_queue); - - sess = session_new(&conf->agent_fe, NULL, &appctx->obj_type); - if (!sess) - goto out_free_spoe; - - appctx->sess = sess; - cs = cs_new_from_endp(appctx->endp, sess, &BUF_NULL); - if (!cs) - goto out_free_spoe; - - strm = DISGUISE(cs_strm(cs)); - stream_set_backend(strm, conf->agent->b.be); - - /* applet is waiting for data */ - cs_cant_get(strm->csf); appctx_wakeup(appctx); - - strm->do_log = NULL; - strm->res.flags |= CF_READ_DONTWAIT; - - HA_SPIN_LOCK(SPOE_APPLET_LOCK, &conf->agent->rt[tid].lock); - LIST_APPEND(&conf->agent->rt[tid].applets, &SPOE_APPCTX(appctx)->list); - HA_SPIN_UNLOCK(SPOE_APPLET_LOCK, &conf->agent->rt[tid].lock); - _HA_ATOMIC_INC(&conf->agent->counters.applets); - - task_wakeup(SPOE_APPCTX(appctx)->task, TASK_WOKEN_INIT); return appctx; /* Error unrolling */ - out_free_spoe: - task_destroy(SPOE_APPCTX(appctx)->task); - out_free_spoe_appctx: - pool_free(pool_head_spoe_appctx, SPOE_APPCTX(appctx)); out_free_appctx: - appctx_free(appctx); + appctx_free_on_early_error(appctx); + out_free_spoe_appctx: + pool_free(pool_head_spoe_appctx, spoe_appctx); out_error: return NULL; }