MINOR: conn-stream: Make cs_detach_* private and use cs_destroy() from outside

A conn-stream is never detached from an endpoint or an application alone,
except on a reset. Thus, to avoid any error, these functions are now
private. And cs_destroy() function is added to destroy a conn-stream. This
function is called when a stream is released, on the front and back
conn-streams, and when a health-check is finished.
This commit is contained in:
Christopher Faulet 2022-04-21 14:22:53 +02:00
parent c6b60f1e00
commit eb50c01fef
5 changed files with 43 additions and 22 deletions

View File

@ -47,9 +47,8 @@ void cs_free(struct conn_stream *cs);
int cs_attach_mux(struct conn_stream *cs, void *target, void *ctx);
int cs_attach_strm(struct conn_stream *cs, struct stream *strm);
void cs_destroy(struct conn_stream *cs);
int cs_reset_endp(struct conn_stream *cs);
void cs_detach_endp(struct conn_stream *cs);
void cs_detach_app(struct conn_stream *cs);
struct appctx *cs_applet_create(struct conn_stream *cs, struct applet *app);
void cs_applet_shut(struct conn_stream *cs);

View File

@ -1199,8 +1199,7 @@ struct task *process_chk_conn(struct task *t, void *context, unsigned int state)
* the tasklet
*/
tasklet_remove_from_tasklet_list(check->wait_list.tasklet);
cs_detach_endp(cs);
cs_detach_app(cs);
cs_destroy(cs);
cs = check->cs = NULL;
conn = NULL;
}
@ -1364,8 +1363,7 @@ void free_check(struct check *check)
check_release_buf(check, &check->bi);
check_release_buf(check, &check->bo);
if (check->cs) {
cs_detach_endp(check->cs);
cs_detach_app(check->cs);
cs_destroy(check->cs);
check->cs = NULL;
}
}

View File

@ -244,13 +244,18 @@ void cs_free(struct conn_stream *cs)
pool_free(pool_head_connstream, cs);
}
/* Conditionally removes a conn-stream if it is detached and it there is no app
* layer defined. Except on error path, this one must be used.
/* Conditionally removes a conn-stream if it is detached and if there is no app
* layer defined. Except on error path, this one must be used. if release, the
* pointer on the CS is set to NULL.
*/
static void cs_free_cond(struct conn_stream *cs)
static void cs_free_cond(struct conn_stream **csp)
{
if (!cs->app && (!cs->endp || (cs->endp->flags & CS_EP_DETACHED)))
struct conn_stream *cs = *csp;
if (!cs->app && (!cs->endp || (cs->endp->flags & CS_EP_DETACHED))) {
cs_free(cs);
*csp = NULL;
}
}
@ -344,8 +349,13 @@ int cs_attach_strm(struct conn_stream *cs, struct stream *strm)
* endpoint is reset and flag as detached. If the app layer is also detached,
* the conn-stream is released.
*/
void cs_detach_endp(struct conn_stream *cs)
static void cs_detach_endp(struct conn_stream **csp)
{
struct conn_stream *cs = *csp;
if (!cs)
return;
if (!cs->endp)
goto reset_cs;
@ -394,14 +404,19 @@ void cs_detach_endp(struct conn_stream *cs)
if (cs_strm(cs))
cs->ops = &cs_app_embedded_ops;
cs->data_cb = NULL;
cs_free_cond(cs);
cs_free_cond(csp);
}
/* Detaches the conn_stream from the app layer. If there is no endpoint attached
* to the conn_stream
*/
void cs_detach_app(struct conn_stream *cs)
static void cs_detach_app(struct conn_stream **csp)
{
struct conn_stream *cs = *csp;
if (!cs)
return;
cs->app = NULL;
cs->data_cb = NULL;
sockaddr_free(&cs->src);
@ -411,7 +426,17 @@ void cs_detach_app(struct conn_stream *cs)
tasklet_free(cs->wait_event.tasklet);
cs->wait_event.tasklet = NULL;
cs->wait_event.events = 0;
cs_free_cond(cs);
cs_free_cond(csp);
}
/* Destroy the conn_stream. It is detached from its endpoint and its
* application. After this call, the conn_stream must be considered as released.
*/
void cs_destroy(struct conn_stream *cs)
{
cs_detach_endp(&cs);
cs_detach_app(&cs);
BUG_ON_HOT(cs);
}
/* Resets the conn-stream endpoint. It happens when the app layer want to renew
@ -426,9 +451,10 @@ int cs_reset_endp(struct conn_stream *cs)
if (!__cs_endp_target(cs)) {
/* endpoint not attached or attached to a mux with no
* target. Thus the endpoint will not be release but just
* reset
* reset. The app is still attached, the cs will not be
* released.
*/
cs_detach_endp(cs);
cs_detach_endp(&cs);
return 0;
}
@ -440,7 +466,8 @@ int cs_reset_endp(struct conn_stream *cs)
return -1;
}
cs_detach_endp(cs);
/* The app is still attached, the cs will not be released */
cs_detach_endp(&cs);
BUG_ON(cs->endp);
cs->endp = new_endp;
cs->endp->flags |= CS_EP_DETACHED;

View File

@ -519,7 +519,6 @@ struct appctx *httpclient_start(struct httpclient *hc)
s->target = &httpclient_srv_ssl->obj_type;
#else
ha_alert("httpclient: OpenSSL is not available %s:%d.\n", __FUNCTION__, __LINE__);
cs_detach_app(cs);
LIST_DELETE(&s->list);
pool_free(pool_head_stream, s);
cs_free(cs);

View File

@ -714,10 +714,8 @@ static void stream_free(struct stream *s)
/* FIXME: Handle it in appctx_free ??? */
must_free_sess = objt_appctx(sess->origin) && sess->origin == __cs_endp_target(s->csf);
cs_detach_endp(s->csb);
cs_detach_endp(s->csf);
cs_detach_app(s->csb);
cs_detach_app(s->csf);
cs_destroy(s->csb);
cs_destroy(s->csf);
if (must_free_sess) {
sess->origin = NULL;