From: Frédéric Lécaille Date: Mon, 20 Sep 2021 15:58:22 +0000 (+0200) Subject: MINOR: quic: Wake up the xprt from mux X-Git-Tag: v2.5-dev8~26 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8526f14acd4f240d52d3cf7bc90858f6e305d12a;p=thirdparty%2Fhaproxy.git MINOR: quic: Wake up the xprt from mux We wake up the xprt as soon as STREAM frames have been pushed to the TX mux buffer (->tx.buf). We also make the mux subscribe() to the xprt layer if some data remain in its ring buffer after having try to transfer them to the xprt layer (TX mux buffer for the stream full). Also do not consider a buffer in the ring if not allocated (see b_size(buf)) condition in the for(;;) loop. Make a call to qc_process_mux() if possible when entering qc_send() to fill the mux with data from streams in the send or flow control lists. --- diff --git a/src/mux_quic.c b/src/mux_quic.c index 8d2473a834..f17ccd2063 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -1346,8 +1346,14 @@ static int qc_send(struct qcc *qcc) { struct qcs *qcs; struct eb64_node *node; + int ret, done; TRACE_ENTER(QC_EV_QCC_SEND, qcc->conn); + ret = done = 0; + /* fill as much as we can into the current buffer */ + while (((qcc->flags & (QC_CF_MUX_MFULL|QC_CF_MUX_MALLOC)) == 0) && !done) + done = qc_process_mux(qcc); + /* TODO simple loop through all streams and check if there is frames to * send */ @@ -1355,9 +1361,8 @@ static int qc_send(struct qcc *qcc) while (node) { struct buffer *buf; qcs = container_of(node, struct qcs, by_id); - for (buf = br_head(qcs->tx.mbuf); b_data(buf); buf = br_del_head(qcs->tx.mbuf)) { + for (buf = br_head(qcs->tx.mbuf); b_size(buf); buf = br_del_head(qcs->tx.mbuf)) { if (b_data(buf)) { - int ret; char fin = 0; /* if FIN is activated, ensure the buffer to @@ -1369,17 +1374,24 @@ static int qc_send(struct qcc *qcc) } ret = qcs_push_frame(qcs, buf, fin, qcs->tx.offset); - if (ret <= 0) + if (ret < 0) ABORT_NOW(); qcs->tx.left -= ret; qcs->tx.offset += ret; - qcs->qcc->wait_event.events &= ~SUB_RETRY_SEND; + if (b_data(buf)) { + qcc->conn->xprt->subscribe(qcc->conn, qcc->conn->xprt_ctx, + SUB_RETRY_SEND, &qcc->wait_event); + break; + } } b_free(buf); } node = eb64_next(node); } + if (ret > 0) + tasklet_wakeup(((struct ssl_sock_ctx *)(qcc->conn->xprt_ctx))->wait_event.tasklet); + TRACE_LEAVE(QC_EV_QCC_SEND, qcc->conn); return 0;