]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: mux-fcgi: Use a dedicated function to resume streams eligible for sending
authorChristopher Faulet <cfaulet@haproxy.com>
Thu, 5 Mar 2026 13:29:52 +0000 (14:29 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Thu, 5 Mar 2026 14:35:36 +0000 (15:35 +0100)
The same code was duplicated in fcgi_process_mux() and fcgi_sedn(). So let's
move it in a dedicated function.

src/mux_fcgi.c

index 5f84b1183fed709a0076e6713a83062ea948eb53..45adb9fbb3b4ef05ebd65482ac19693f179d51f3 100644 (file)
@@ -2724,13 +2724,42 @@ static void fcgi_process_demux(struct fcgi_conn *fconn)
        fcgi_conn_restart_reading(fconn, 0);
 }
 
+/* resume each fstrm eligible for sending in list head <head> */
+static void fcgi_resume_each_sending_fstrm(struct fcgi_conn *fconn, struct list *head)
+{
+       struct fcgi_strm *fstrm, *fstrm_back;
+
+       TRACE_ENTER(FCGI_EV_FCONN_SEND|FCGI_EV_FCONN_WAKE, fconn->conn);
+
+       list_for_each_entry_safe(fstrm, fstrm_back, &fconn->send_list, send_list) {
+               if (fconn->state == FCGI_CS_CLOSED || fconn->flags & FCGI_CF_MUX_BLOCK_ANY)
+                       break;
+
+               fstrm->flags &= ~FCGI_SF_BLK_ANY;
+
+               if (fstrm->flags & FCGI_SF_NOTIFIED)
+                       continue;
+
+               /* If the sender changed his mind and unsubscribed, let's just
+                * remove the stream from the send_list.
+                */
+               if (!(fstrm->flags & (FCGI_SF_WANT_SHUTR|FCGI_SF_WANT_SHUTW)) &&
+                   (!fstrm->subs || !(fstrm->subs->events & SUB_RETRY_SEND))) {
+                       LIST_DEL_INIT(&fstrm->send_list);
+                       continue;
+               }
+
+               fcgi_strm_notify_send(fstrm);
+       }
+
+       TRACE_LEAVE(FCGI_EV_FCONN_SEND|FCGI_EV_FCONN_WAKE, fconn->conn);
+}
+
 /* process Tx records from streams to be multiplexed. Returns > 0 if it reached
  * the end.
  */
 static int fcgi_process_mux(struct fcgi_conn *fconn)
 {
-       struct fcgi_strm *fstrm, *fstrm_back;
-
        TRACE_ENTER(FCGI_EV_FCONN_WAKE, fconn->conn);
 
        if (unlikely(fconn->state < FCGI_CS_RECORD_H)) {
@@ -2753,36 +2782,7 @@ static int fcgi_process_mux(struct fcgi_conn *fconn)
        }
 
   mux:
-       list_for_each_entry_safe(fstrm, fstrm_back, &fconn->send_list, send_list) {
-               if (fconn->state == FCGI_CS_CLOSED || fconn->flags & FCGI_CF_MUX_BLOCK_ANY)
-                       break;
-
-               if (fstrm->flags & FCGI_SF_NOTIFIED)
-                       continue;
-
-               /* If the sender changed his mind and unsubscribed, let's just
-                * remove the stream from the send_list.
-                */
-               if (!(fstrm->flags & (FCGI_SF_WANT_SHUTR|FCGI_SF_WANT_SHUTW)) &&
-                   (!fstrm->subs || !(fstrm->subs->events & SUB_RETRY_SEND))) {
-                       LIST_DEL_INIT(&fstrm->send_list);
-                       continue;
-               }
-
-               if (fstrm->subs && fstrm->subs->events & SUB_RETRY_SEND) {
-                       TRACE_POINT(FCGI_EV_STRM_WAKE, fconn->conn, fstrm);
-                       fstrm->flags &= ~FCGI_SF_BLK_ANY;
-                       fstrm->flags |= FCGI_SF_NOTIFIED;
-                       tasklet_wakeup(fstrm->subs->tasklet);
-                       fstrm->subs->events &= ~SUB_RETRY_SEND;
-                       if (!fstrm->subs->events)
-                               fstrm->subs = NULL;
-               } else {
-                       /* it's the shut request that was queued */
-                       TRACE_POINT(FCGI_EV_STRM_WAKE, fconn->conn, fstrm);
-                       tasklet_wakeup(fstrm->shut_tl);
-               }
-       }
+       fcgi_resume_each_sending_fstrm(fconn, &fconn->send_list);
 
  fail:
        if (fconn->state == FCGI_CS_CLOSED) {
@@ -2986,40 +2986,9 @@ static int fcgi_send(struct fcgi_conn *fconn)
        /* We're not full anymore, so we can wake any task that are waiting
         * for us.
         */
-       if (!(fconn->flags & (FCGI_CF_MUX_MFULL | FCGI_CF_DEM_MROOM)) && fconn->state >= FCGI_CS_RECORD_H) {
-               struct fcgi_strm *fstrm, *fstrm_back;
-
-               list_for_each_entry_safe(fstrm, fstrm_back, &fconn->send_list, send_list) {
-                       if (fconn->state == FCGI_CS_CLOSED || fconn->flags & FCGI_CF_MUX_BLOCK_ANY)
-                               break;
-
-                       if (fstrm->flags & FCGI_SF_NOTIFIED)
-                               continue;
+       if (!(fconn->flags & (FCGI_CF_MUX_MFULL | FCGI_CF_DEM_MROOM)) && fconn->state >= FCGI_CS_RECORD_H)
+               fcgi_resume_each_sending_fstrm(fconn, &fconn->send_list);
 
-                       /* If the sender changed his mind and unsubscribed, let's just
-                        * remove the stream from the send_list.
-                        */
-                       if (!(fstrm->flags & (FCGI_SF_WANT_SHUTR|FCGI_SF_WANT_SHUTW)) &&
-                           (!fstrm->subs || !(fstrm->subs->events & SUB_RETRY_SEND))) {
-                               LIST_DEL_INIT(&fstrm->send_list);
-                               continue;
-                       }
-
-                       if (fstrm->subs && fstrm->subs->events & SUB_RETRY_SEND) {
-                               TRACE_DEVEL("waking up pending stream", FCGI_EV_FCONN_SEND|FCGI_EV_STRM_WAKE, conn, fstrm);
-                               fstrm->flags &= ~FCGI_SF_BLK_ANY;
-                               fstrm->flags |= FCGI_SF_NOTIFIED;
-                               tasklet_wakeup(fstrm->subs->tasklet);
-                               fstrm->subs->events &= ~SUB_RETRY_SEND;
-                               if (!fstrm->subs->events)
-                                       fstrm->subs = NULL;
-                       } else {
-                               /* it's the shut request that was queued */
-                               TRACE_POINT(FCGI_EV_STRM_WAKE, fconn->conn, fstrm);
-                               tasklet_wakeup(fstrm->shut_tl);
-                       }
-               }
-       }
        /* We're done, no more to send */
        if (!br_data(fconn->mbuf)) {
                TRACE_DEVEL("leaving with everything sent", FCGI_EV_FCONN_SEND, conn);