]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: quic: Let it be known if the tasklet has been released.
authorOlivier Houchard <cognet@ci0.org>
Thu, 1 May 2025 12:39:39 +0000 (14:39 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 2 May 2025 09:09:28 +0000 (11:09 +0200)
quic_conn_release() may, or may not, free the tasklet associated with
the connection. So make it return 1 if it was, and 0 otherwise, so that
if it was called from the tasklet handler itself, the said handler can
act accordingly and return NULL if the tasklet was destroyed.
This should be backported if 9240cd4a2771245fae4d0d69ef025104b14bfc23
is backported.

include/haproxy/quic_conn.h
src/quic_conn.c

index 3ba4b09383cc3656a96f9962cdf137ad4e96c85b..b6a416644778f97a1d19348594f86980874e96f1 100644 (file)
@@ -174,7 +174,7 @@ int qc_notify_send(struct quic_conn *qc);
 
 void qc_check_close_on_released_mux(struct quic_conn *qc);
 
-void quic_conn_release(struct quic_conn *qc);
+int quic_conn_release(struct quic_conn *qc);
 
 void qc_kill_conn(struct quic_conn *qc);
 
index 882158c766dd92cd03766aac66dc04c912bb476d..5b04dbfc12347f957d7e4facf1d90f1ab8cfb4f9 100644 (file)
@@ -625,8 +625,8 @@ struct task *quic_conn_app_io_cb(struct task *t, void *context, unsigned int sta
 
  out:
        if ((qc->flags & QUIC_FL_CONN_CLOSING) && qc->mux_state != QC_MUX_READY) {
-               quic_conn_release(qc);
-               t = NULL;
+               if (quic_conn_release(qc))
+                       t = NULL;
                qc = NULL;
        }
 
@@ -904,7 +904,8 @@ struct task *quic_conn_io_cb(struct task *t, void *context, unsigned int state)
        }
 
        if ((qc->flags & QUIC_FL_CONN_CLOSING) && qc->mux_state != QC_MUX_READY) {
-               quic_conn_release(qc);
+               if (quic_conn_release(qc))
+                       t = NULL;
                qc = NULL;
        }
 
@@ -1392,12 +1393,15 @@ static inline void quic_conn_prx_cntrs_update(struct quic_conn *qc)
  *
  * This function must only be called by the thread responsible of the quic_conn
  * tasklet.
+ *
+ * Returns 1 if the tasklet was released, 0 otherwise
  */
-void quic_conn_release(struct quic_conn *qc)
+int quic_conn_release(struct quic_conn *qc)
 {
        struct eb64_node *node;
        struct quic_rx_packet *pkt, *pktback;
        struct quic_conn_closed *cc_qc;
+       int ret = 0;
 
        TRACE_ENTER(QUIC_EV_CONN_CLOSE, qc);
 
@@ -1425,6 +1429,7 @@ void quic_conn_release(struct quic_conn *qc)
                qc->cids = NULL;
                pool_free(pool_head_quic_cc_buf, qc->tx.cc_buf_area);
                qc->tx.cc_buf_area = NULL;
+               ret = 1;
        }
 
        if (qc_test_fd(qc))
@@ -1525,6 +1530,7 @@ void quic_conn_release(struct quic_conn *qc)
        TRACE_PROTO("QUIC conn. freed", QUIC_EV_CONN_FREED, qc);
  leave:
        TRACE_LEAVE(QUIC_EV_CONN_CLOSE, qc);
+       return ret;
 }
 
 /* Initialize the timer task of <qc> QUIC connection.