]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: mux-quic: reorganize code for app init/shutdown
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 15 Apr 2026 07:36:55 +0000 (09:36 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 15 Apr 2026 12:34:13 +0000 (14:34 +0200)
Refactor code related to app-layer init/shutdown operations. In short,
qcc_shutdown() is renamed to qcc_app_shutdown(). It is also moved next
to qcc_app_init() to better reflect their link.

src/mux_quic.c

index a2cb8864a16447600d8d884b1551aff6d3ab9f93..607d9afe96bd714c3d247fe17f6d074b17f6ab2a 100644 (file)
@@ -44,6 +44,9 @@ DECLARE_STATIC_TYPED_POOL(pool_head_qc_stream_rxbuf, "qc_stream_rxbuf", struct q
 static void qmux_ctrl_send(struct qc_stream_desc *, uint64_t data, uint64_t offset);
 static void qmux_ctrl_room(struct qc_stream_desc *, uint64_t room);
 
+static int qcc_app_init(struct qcc *qcc);
+static void qcc_app_shutdown(struct qcc *qcc);
+
 /* Returns true if pacing should be used for <conn> connection. */
 static int qcc_is_pacing_active(const struct connection *conn)
 {
@@ -2959,42 +2962,6 @@ static void qcc_wakeup_pacing(struct qcc *qcc)
        ++qcc->tx.paced_sent_ctr;
 }
 
-/* Conduct I/O operations to finalize <qcc> app layer initialization. Note that
- * <qcc> app state may remain NULL even on success, if only a transient
- * blocking was encountered. Finalize operation can be retry later.
- *
- * Returns 0 on success else non-zero.
- */
-static int qcc_app_init(struct qcc *qcc)
-{
-       int ret;
-
-       TRACE_ENTER(QMUX_EV_QCC_SEND, qcc->conn);
-
-       if (qcc->app_ops->finalize) {
-               ret = qcc->app_ops->finalize(qcc->ctx);
-               if (ret < 0) {
-                       TRACE_ERROR("app ops finalize error", QMUX_EV_QCC_NEW, qcc->conn);
-                       goto err;
-               }
-
-               if (ret) {
-                       TRACE_STATE("cannot finalize app ops yet", QMUX_EV_QCC_NEW, qcc->conn);
-                       goto again;
-               }
-       }
-
-       qcc->app_st = QCC_APP_ST_INIT;
-
- again:
-       TRACE_LEAVE(QMUX_EV_QCC_SEND, qcc->conn);
-       return 0;
-
- err:
-       TRACE_DEVEL("leaving on error", QMUX_EV_QCC_SEND, qcc->conn);
-       return 1;
-}
-
 /* Proceed to sending. Loop through all available streams for the <qcc>
  * instance and try to send as much as possible.
  *
@@ -3276,52 +3243,6 @@ static void qcc_purge_streams(struct qcc *qcc)
        TRACE_LEAVE(QMUX_EV_QCC_WAKE, qcc->conn);
 }
 
-/* Execute application layer shutdown. If this operation is not defined, a
- * CONNECTION_CLOSE will be prepared as a fallback. This function is protected
- * against multiple invocation thanks to <qcc> application state context.
- */
-static void qcc_shutdown(struct qcc *qcc)
-{
-       TRACE_ENTER(QMUX_EV_QCC_END, qcc->conn);
-
-       if (qcc->flags & (QC_CF_ERR_CONN|QC_CF_ERRL)) {
-               TRACE_DATA("connection on error", QMUX_EV_QCC_END, qcc->conn);
-               goto out;
-       }
-
-       if (qcc->app_st >= QCC_APP_ST_SHUT)
-               goto out;
-
-       TRACE_STATE("perform graceful shutdown", QMUX_EV_QCC_END, qcc->conn);
-       if (qcc->app_ops && qcc->app_ops->shutdown) {
-               qcc->app_ops->shutdown(qcc->ctx);
-               qcc_io_send(qcc);
-       }
-       else {
-               qcc->err = quic_err_transport(QC_ERR_NO_ERROR);
-       }
-
-       if (conn_is_quic(qcc->conn)) {
-               /* Register "no error" code at transport layer. Do not use
-                * quic_set_connection_close() as retransmission may be performed to
-                * finalized transfers. Do not overwrite quic-conn existing code if
-                * already set.
-                *
-                * TODO implement a wrapper function for this in quic-conn module
-                */
-               if (!(qcc->conn->handle.qc->flags & QUIC_FL_CONN_IMMEDIATE_CLOSE))
-                       qcc->conn->handle.qc->err = qcc->err;
-       }
-
-       /* A connection is not reusable if app layer is closed. */
-       if (qcc->flags & QC_CF_IS_BACK)
-               conn_delete_from_tree(qcc->conn, tid);
-
- out:
-       qcc->app_st = QCC_APP_ST_SHUT;
-       TRACE_LEAVE(QMUX_EV_QCC_END, qcc->conn);
-}
-
 /* Loop through all qcs from <qcc> and wake their associated data layer if
  * still active. Also report error on it if connection is already in error.
  */
@@ -3395,7 +3316,7 @@ static int qcc_io_process(struct qcc *qcc)
                }
 
                if (close)
-                       qcc_shutdown(qcc);
+                       qcc_app_shutdown(qcc);
        }
 
        /* Report error if set on stream endpoint layer. */
@@ -3409,6 +3330,88 @@ static int qcc_io_process(struct qcc *qcc)
        return 0;
 }
 
+/* Conduct I/O operations to finalize <qcc> app layer initialization. Note that
+ * <qcc> app state may remain NULL even on success, if only a transient
+ * blocking was encountered. Finalize operation can be retry later.
+ *
+ * Returns 0 on success else non-zero.
+ */
+static int qcc_app_init(struct qcc *qcc)
+{
+       int ret;
+
+       TRACE_ENTER(QMUX_EV_QCC_SEND, qcc->conn);
+
+       if (qcc->app_ops->finalize) {
+               ret = qcc->app_ops->finalize(qcc->ctx);
+               if (ret < 0) {
+                       TRACE_ERROR("app ops finalize error", QMUX_EV_QCC_NEW, qcc->conn);
+                       goto err;
+               }
+
+               if (ret) {
+                       TRACE_STATE("cannot finalize app ops yet", QMUX_EV_QCC_NEW, qcc->conn);
+                       goto again;
+               }
+       }
+
+       qcc->app_st = QCC_APP_ST_INIT;
+
+ again:
+       TRACE_LEAVE(QMUX_EV_QCC_SEND, qcc->conn);
+       return 0;
+
+ err:
+       TRACE_DEVEL("leaving on error", QMUX_EV_QCC_SEND, qcc->conn);
+       return 1;
+}
+
+/* Execute application layer shutdown. If this operation is not defined, a
+ * CONNECTION_CLOSE will be prepared as a fallback. This function is protected
+ * against multiple invocation thanks to <qcc> application state context.
+ */
+static void qcc_app_shutdown(struct qcc *qcc)
+{
+       TRACE_ENTER(QMUX_EV_QCC_END, qcc->conn);
+
+       if (qcc->flags & (QC_CF_ERR_CONN|QC_CF_ERRL)) {
+               TRACE_DATA("connection on error", QMUX_EV_QCC_END, qcc->conn);
+               goto out;
+       }
+
+       if (qcc->app_st >= QCC_APP_ST_SHUT)
+               goto out;
+
+       TRACE_STATE("perform graceful shutdown", QMUX_EV_QCC_END, qcc->conn);
+       if (qcc->app_ops && qcc->app_ops->shutdown) {
+               qcc->app_ops->shutdown(qcc->ctx);
+               qcc_io_send(qcc);
+       }
+       else {
+               qcc->err = quic_err_transport(QC_ERR_NO_ERROR);
+       }
+
+       if (conn_is_quic(qcc->conn)) {
+               /* Register "no error" code at transport layer. Do not use
+                * quic_set_connection_close() as retransmission may be performed to
+                * finalized transfers. Do not overwrite quic-conn existing code if
+                * already set.
+                *
+                * TODO implement a wrapper function for this in quic-conn module
+                */
+               if (!(qcc->conn->handle.qc->flags & QUIC_FL_CONN_IMMEDIATE_CLOSE))
+                       qcc->conn->handle.qc->err = qcc->err;
+       }
+
+       /* A connection is not reusable if app layer is closed. */
+       if (qcc->flags & QC_CF_IS_BACK)
+               conn_delete_from_tree(qcc->conn, tid);
+
+ out:
+       qcc->app_st = QCC_APP_ST_SHUT;
+       TRACE_LEAVE(QMUX_EV_QCC_END, qcc->conn);
+}
+
 /* Free all resources allocated for <qcc> connection. */
 static void qcc_release(struct qcc *qcc)
 {
@@ -3585,7 +3588,7 @@ struct task *qcc_io_cb(struct task *t, void *ctx, unsigned int state)
        return t;
 
  release:
-       qcc_shutdown(qcc);
+       qcc_app_shutdown(qcc);
        qcc_release(qcc);
 
        TRACE_LEAVE(QMUX_EV_QCC_WAKE);
@@ -3675,7 +3678,7 @@ static struct task *qcc_timeout_task(struct task *t, void *ctx, unsigned int sta
         */
        if (qcc_is_dead(qcc)) {
                TRACE_STATE("releasing dead connection", QMUX_EV_QCC_WAKE, qcc->conn);
-               qcc_shutdown(qcc);
+               qcc_app_shutdown(qcc);
                qcc_release(qcc);
        }
 
@@ -4142,7 +4145,7 @@ static void qmux_strm_detach(struct sedesc *sd)
        return;
 
  release:
-       qcc_shutdown(qcc);
+       qcc_app_shutdown(qcc);
        qcc_release(qcc);
        TRACE_LEAVE(QMUX_EV_STRM_END);
        return;
@@ -4486,7 +4489,7 @@ static int qmux_wake(struct connection *conn)
        return 0;
 
  release:
-       qcc_shutdown(qcc);
+       qcc_app_shutdown(qcc);
        qcc_release(qcc);
        TRACE_LEAVE(QMUX_EV_QCC_WAKE);
        return 1;