MEDIUM: applet: Set the appctx owner during allocation

The appctx owner is now always a conn-stream. Thus, it can be set during the
appctx allocation. But, to do so, the conn-stream must be created first. It
is not a problem on the server side because the conn-stream is created with
the stream. On the client side, we must take care to create the conn-stream
first.

This change should ease other changes about the applets bootstrapping.
This commit is contained in:
Christopher Faulet 2022-01-19 14:50:11 +01:00
parent 81a40f630e
commit 2479e5f775
8 changed files with 77 additions and 72 deletions

View File

@ -59,7 +59,7 @@ static inline void appctx_init(struct appctx *appctx)
* appctx_free(). <applet> is assigned as the applet, but it can be NULL. The
* applet's task is always created on the current thread.
*/
static inline struct appctx *appctx_new(struct applet *applet)
static inline struct appctx *appctx_new(struct applet *applet, void *owner)
{
struct appctx *appctx;
@ -67,6 +67,7 @@ static inline struct appctx *appctx_new(struct applet *applet)
if (likely(appctx != NULL)) {
appctx->obj_type = OBJ_TYPE_APPCTX;
appctx->applet = applet;
appctx->owner = owner;
appctx_init(appctx);
appctx->t = task_new_here();
if (unlikely(appctx->t == NULL)) {

View File

@ -891,10 +891,15 @@ static struct appctx *dns_session_create(struct dns_session *ds)
struct stream *s;
struct applet *applet = &dns_session_applet;
appctx = appctx_new(applet);
if (!appctx)
cs = cs_new();
if (!cs) {
ha_alert("out of memory in dns_session_create().\n");
goto out_close;
}
appctx = appctx_new(applet, cs);
if (!appctx)
goto out_free_cs;
appctx->ctx.sft.ptr = (void *)ds;
sess = session_new(ds->dss->srv->proxy, NULL, &appctx->obj_type);
@ -903,22 +908,16 @@ static struct appctx *dns_session_create(struct dns_session *ds)
goto out_free_appctx;
}
cs = cs_new();
if (!cs) {
ha_alert("out of memory in dns_session_create().\n");
goto out_free_sess;
}
cs_attach_endp(cs, &appctx->obj_type, appctx);
if ((s = stream_new(sess, cs, &BUF_NULL)) == NULL) {
ha_alert("Failed to initialize stream in dns_session_create().\n");
goto out_free_cs;
goto out_free_sess;
}
s->target = &ds->dss->srv->obj_type;
if (!sockaddr_alloc(&cs_si(s->csb)->dst, &ds->dss->srv->addr, sizeof(ds->dss->srv->addr)))
goto out_free_strm;
cs_attach_endp(cs, &appctx->obj_type, appctx);
s->flags = SF_ASSIGNED|SF_ADDR_SET;
cs_si(s->csb)->flags |= SI_FL_NOLINGER;
@ -938,12 +937,12 @@ static struct appctx *dns_session_create(struct dns_session *ds)
out_free_strm:
LIST_DELETE(&s->list);
pool_free(pool_head_stream, s);
out_free_cs:
cs_free(cs);
out_free_sess:
session_free(sess);
out_free_appctx:
appctx_free(appctx);
out_free_cs:
cs_free(cs);
out_close:
return NULL;
}

View File

@ -1991,9 +1991,13 @@ spoe_create_appctx(struct spoe_config *conf)
struct conn_stream *cs;
struct stream *strm;
if ((appctx = appctx_new(&spoe_applet)) == NULL)
cs = cs_new();
if (!cs)
goto out_error;
if ((appctx = appctx_new(&spoe_applet, cs)) == NULL)
goto out_free_cs;
appctx->ctx.spoe.ptr = pool_zalloc(pool_head_spoe_appctx);
if (SPOE_APPCTX(appctx) == NULL)
goto out_free_appctx;
@ -2024,14 +2028,10 @@ spoe_create_appctx(struct spoe_config *conf)
if (!sess)
goto out_free_spoe;
cs = cs_new();
if (!cs)
goto out_free_sess;
cs_attach_endp(cs, &appctx->obj_type, appctx);
if ((strm = stream_new(sess, cs, &BUF_NULL)) == NULL)
goto out_free_cs;
goto out_free_sess;
cs_attach_endp(cs, &appctx->obj_type, appctx);
stream_set_backend(strm, conf->agent->b.be);
/* applet is waiting for data */
@ -2050,8 +2050,6 @@ spoe_create_appctx(struct spoe_config *conf)
return appctx;
/* Error unrolling */
out_free_cs:
cs_free(cs);
out_free_sess:
session_free(sess);
out_free_spoe:
@ -2060,6 +2058,8 @@ spoe_create_appctx(struct spoe_config *conf)
pool_free(pool_head_spoe_appctx, SPOE_APPCTX(appctx));
out_free_appctx:
appctx_free(appctx);
out_free_cs:
cs_free(cs);
out_error:
return NULL;
}

View File

@ -2944,13 +2944,19 @@ __LJMP static int hlua_socket_new(lua_State *L)
lua_rawgeti(L, LUA_REGISTRYINDEX, class_socket_ref);
lua_setmetatable(L, -2);
/* Create the applet context */
appctx = appctx_new(&update_applet);
if (!appctx) {
cs = cs_new();
if (!cs) {
hlua_pusherror(L, "socket: out of memory");
goto out_fail_conf;
}
/* Create the applet context */
appctx = appctx_new(&update_applet, cs);
if (!appctx) {
hlua_pusherror(L, "socket: out of memory");
goto out_fail_cs;
}
appctx->ctx.hlua_cosocket.connected = 0;
appctx->ctx.hlua_cosocket.die = 0;
LIST_INIT(&appctx->ctx.hlua_cosocket.wake_on_write);
@ -2963,19 +2969,14 @@ __LJMP static int hlua_socket_new(lua_State *L)
goto out_fail_appctx;
}
cs = cs_new();
if (!cs) {
hlua_pusherror(L, "socket: out of memory");
goto out_fail_sess;
}
cs_attach_endp(cs, &appctx->obj_type, appctx);
strm = stream_new(sess, cs, &BUF_NULL);
if (!strm) {
hlua_pusherror(L, "socket: out of memory");
goto out_fail_cs;
goto out_fail_sess;
}
cs_attach_endp(cs, &appctx->obj_type, appctx);
/* Initialise cross reference between stream and Lua socket object. */
xref_create(&socket->xref, &appctx->ctx.hlua_cosocket.xref);
@ -2991,12 +2992,12 @@ __LJMP static int hlua_socket_new(lua_State *L)
return 1;
out_fail_cs:
cs_free(cs);
out_fail_sess:
session_free(sess);
out_fail_appctx:
appctx_free(appctx);
out_fail_cs:
cs_free(cs);
out_fail_conf:
WILL_LJMP(lua_error(L));
return 0;

View File

@ -476,26 +476,27 @@ struct appctx *httpclient_start(struct httpclient *hc)
goto out;
}
cs = cs_new();
if (!cs) {
ha_alert("httpclient: out of memory in %s:%d.\n", __FUNCTION__, __LINE__);
goto out;
}
/* The HTTP client will be created in the same thread as the caller,
* avoiding threading issues */
appctx = appctx_new(applet);
appctx = appctx_new(applet, cs);
if (!appctx)
goto out;
goto out_free_cs;
sess = session_new(httpclient_proxy, NULL, &appctx->obj_type);
if (!sess) {
ha_alert("httpclient: out of memory in %s:%d.\n", __FUNCTION__, __LINE__);
goto out_free_appctx;
}
cs = cs_new();
if (!cs) {
ha_alert("httpclient: out of memory in %s:%d.\n", __FUNCTION__, __LINE__);
goto out_free_sess;
}
cs_attach_endp(cs, &appctx->obj_type, appctx);
if ((s = stream_new(sess, cs, &hc->req.buf)) == NULL) {
ha_alert("httpclient: Failed to initialize stream %s:%d.\n", __FUNCTION__, __LINE__);
goto out_free_cs;
goto out_free_sess;
}
/* set the "timeout server" */
@ -528,6 +529,7 @@ struct appctx *httpclient_start(struct httpclient *hc)
break;
}
cs_attach_endp(cs, &appctx->obj_type, appctx);
s->flags |= SF_ASSIGNED|SF_ADDR_SET;
cs_si(s->csb)->flags |= SI_FL_NOLINGER;
s->res.flags |= CF_READ_DONTWAIT;
@ -550,12 +552,12 @@ struct appctx *httpclient_start(struct httpclient *hc)
out_free_stream:
LIST_DELETE(&s->list);
pool_free(pool_head_stream, s);
out_free_cs:
cs_free(cs);
out_free_sess:
session_free(sess);
out_free_appctx:
appctx_free(appctx);
out_free_cs:
cs_free(cs);
out:
return NULL;

View File

@ -3191,9 +3191,15 @@ static struct appctx *peer_session_create(struct peers *peers, struct peer *peer
peer->last_hdshk = now_ms;
s = NULL;
appctx = appctx_new(&peer_applet);
if (!appctx)
cs = cs_new();
if (!cs) {
ha_alert("out of memory in peer_session_create().\n");
goto out_close;
}
appctx = appctx_new(&peer_applet, cs);
if (!appctx)
goto out_free_cs;
appctx->st0 = PEER_SESS_ST_CONNECT;
appctx->ctx.peers.ptr = (void *)peer;
@ -3204,16 +3210,9 @@ static struct appctx *peer_session_create(struct peers *peers, struct peer *peer
goto out_free_appctx;
}
cs = cs_new();
if (!cs) {
ha_alert("out of memory in peer_session_create().\n");
goto out_free_sess;
}
cs_attach_endp(cs, &appctx->obj_type, appctx);
if ((s = stream_new(sess, cs, &BUF_NULL)) == NULL) {
ha_alert("Failed to initialize stream in peer_session_create().\n");
goto out_free_cs;
goto out_free_sess;
}
/* applet is waiting for data */
@ -3224,6 +3223,8 @@ static struct appctx *peer_session_create(struct peers *peers, struct peer *peer
s->target = peer_session_target(peer, s);
if (!sockaddr_alloc(&(cs_si(s->csb)->dst), &peer->addr, sizeof(peer->addr)))
goto out_free_strm;
cs_attach_endp(cs, &appctx->obj_type, appctx);
s->flags = SF_ASSIGNED|SF_ADDR_SET;
cs_si(s->csb)->flags |= SI_FL_NOLINGER;
@ -3240,12 +3241,12 @@ static struct appctx *peer_session_create(struct peers *peers, struct peer *peer
out_free_strm:
LIST_DELETE(&s->list);
pool_free(pool_head_stream, s);
out_free_cs:
cs_free(cs);
out_free_sess:
session_free(sess);
out_free_appctx:
appctx_free(appctx);
out_free_cs:
cs_free(cs);
out_close:
return NULL;
}

View File

@ -643,9 +643,15 @@ static struct appctx *sink_forward_session_create(struct sink *sink, struct sink
if (sft->srv->log_proto == SRV_LOG_PROTO_OCTET_COUNTING)
applet = &sink_forward_oc_applet;
appctx = appctx_new(applet);
if (!appctx)
cs = cs_new();
if (!cs) {
ha_alert("out of memory in sink_forward_session_create");
goto out_close;
}
appctx = appctx_new(applet, cs);
if (!appctx)
goto out_free_cs;
appctx->ctx.sft.ptr = (void *)sft;
@ -655,22 +661,17 @@ static struct appctx *sink_forward_session_create(struct sink *sink, struct sink
goto out_free_appctx;
}
cs = cs_new();
if (!cs) {
ha_alert("out of memory in sink_forward_session_create");
goto out_free_sess;
}
cs_attach_endp(cs, &appctx->obj_type, appctx);
if ((s = stream_new(sess, cs, &BUF_NULL)) == NULL) {
ha_alert("Failed to initialize stream in sink_forward_session_create().\n");
goto out_free_cs;
goto out_free_sess;
}
s->target = &sft->srv->obj_type;
if (!sockaddr_alloc(&cs_si(s->csb)->dst, &sft->srv->addr, sizeof(sft->srv->addr)))
goto out_free_strm;
cs_attach_endp(cs, &appctx->obj_type, appctx);
s->flags = SF_ASSIGNED|SF_ADDR_SET;
cs_si(s->csb)->flags |= SI_FL_NOLINGER;
@ -690,12 +691,12 @@ static struct appctx *sink_forward_session_create(struct sink *sink, struct sink
out_free_strm:
LIST_DELETE(&s->list);
pool_free(pool_head_stream, s);
out_free_cs:
cs_free(cs);
out_free_sess:
session_free(sess);
out_free_appctx:
appctx_free(appctx);
out_free_cs:
cs_free(cs);
out_close:
return NULL;
}

View File

@ -339,7 +339,7 @@ struct appctx *si_register_handler(struct stream_interface *si, struct applet *a
DPRINTF(stderr, "registering handler %p for si %p (was %p)\n", app, si, si_task(si));
appctx = appctx_new(app);
appctx = appctx_new(app, si->cs);
if (!appctx)
return NULL;
cs_attach_endp(si->cs, &appctx->obj_type, appctx);