]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: stream: Save SC and channel flags earlier in process_steam()
authorChristopher Faulet <cfaulet@haproxy.com>
Mon, 17 Mar 2025 15:07:21 +0000 (16:07 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Thu, 3 Apr 2025 08:19:58 +0000 (10:19 +0200)
At the begining of process_stream(), the flags of the stream connectors and
channels are saved to be able to handle changes performed in sub-functions
(for instance in analyzers). But, some operations were performed before
saving these flags: Synchronous receives and forced shutdowns. While it
seems to safe for now, it is a bit annoying because some events could be
missed.

So, to avoid bugs in the future, the channels and stream connectors flags
are now really saved before any other processing.

src/stream.c

index d6ebe7cad1cc563f908e37d1ef5c2c7718980704..f352f7a90ab225ddda7dd455b7896922fe9be0b8 100644 (file)
@@ -1752,11 +1752,33 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
        struct stconn *scf, *scb;
        unsigned int rate;
 
-       DBG_TRACE_ENTER(STRM_EV_STRM_PROC, s);
-
        activity[tid].stream_calls++;
        stream_cond_update_cpu_latency(s);
 
+       req = &s->req;
+       res = &s->res;
+
+       scf = s->scf;
+       scb = s->scb;
+
+       DBG_TRACE_ENTER(STRM_EV_STRM_PROC, s);
+
+       /* This flag must explicitly be set every time */
+       req->flags &= ~CF_WAKE_WRITE;
+       res->flags &= ~CF_WAKE_WRITE;
+
+       /* Keep a copy of req/rep flags so that we can detect shutdowns */
+       rqf_last = req->flags & ~CF_MASK_ANALYSER;
+       rpf_last = res->flags & ~CF_MASK_ANALYSER;
+
+       /* we don't want the stream connector functions to recursively wake us up */
+       scf->flags |= SC_FL_DONT_WAKE;
+       scb->flags |= SC_FL_DONT_WAKE;
+
+       /* Keep a copy of SC flags */
+       scf_flags = scf->flags;
+       scb_flags = scb->flags;
+
        /* update pending events */
        s->pending_events |= stream_map_task_state(state);
        s->pending_events |= HA_ATOMIC_XCHG(&s->new_events, STRM_EVT_NONE);
@@ -1768,12 +1790,6 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
                                         SF_ERR_KILLED));
        }
 
-       req = &s->req;
-       res = &s->res;
-
-       scf = s->scf;
-       scb = s->scb;
-
        /* First, attempt to receive pending data from I/O layers */
        sc_sync_recv(scf);
        sc_sync_recv(scb);
@@ -1792,22 +1808,6 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
        if (s->txn)
                memset(&s->txn->auth, 0, sizeof(s->txn->auth));
 
-       /* This flag must explicitly be set every time */
-       req->flags &= ~CF_WAKE_WRITE;
-       res->flags &= ~CF_WAKE_WRITE;
-
-       /* Keep a copy of req/rep flags so that we can detect shutdowns */
-       rqf_last = req->flags & ~CF_MASK_ANALYSER;
-       rpf_last = res->flags & ~CF_MASK_ANALYSER;
-
-       /* we don't want the stream connector functions to recursively wake us up */
-       scf->flags |= SC_FL_DONT_WAKE;
-       scb->flags |= SC_FL_DONT_WAKE;
-
-       /* Keep a copy of SC flags */
-       scf_flags = scf->flags;
-       scb_flags = scb->flags;
-
        /* 1a: Check for low level timeouts if needed. We just set a flag on
         * stream connectors when their timeouts have expired.
         */