]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: conn-stream: Make cs_detach_* private and use cs_destroy() from outside
authorChristopher Faulet <cfaulet@haproxy.com>
Thu, 21 Apr 2022 12:22:53 +0000 (14:22 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 22 Apr 2022 12:32:30 +0000 (14:32 +0200)
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.

include/haproxy/conn_stream.h
src/check.c
src/conn_stream.c
src/http_client.c
src/stream.c

index 8511b96df391084514b060d38dd8e9c6db89f611..2d5cc4ffa42a5370c85acd1b4e172cbca96bc8e5 100644 (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);
index 71d3f3cdd5d90266592cf9b8d957db2831ca3f8f..c39561a508fcf57be410932cd607073ad6fcad7e 100644 (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;
        }
 }
index e753749ca92d535810cec55cf9d16b7b3a637551..fda8ab44e882d604f824d355fc67de8ea91f67f7 100644 (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;
index 6bf28d03b9b46c205b2e3795fb1fd25b36213d9a..57ca92839f9272cb43916ad13a902a599c851f00 100644 (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);
index ace922d31da11c92fecd9524d04f111e29bde5fd..3d5c7406914e8da7a182386c2fbc1185beada2b3 100644 (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;