]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: channel: Use CF_WRITE_EVENT instead of CF_WRITE_PARTIAL
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 20 Dec 2022 17:10:04 +0000 (18:10 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 9 Jan 2023 17:41:08 +0000 (18:41 +0100)
Just like CF_READ_PARTIAL, CF_WRITE_PARTIAL is now merged with
CF_WRITE_EVENT. There a subtlety in sc_notify(). The "connect" event
(formely CF_WRITE_NULL) is now detected with
(CF_WRITE_EVENT + sc->state < SC_ST_EST).

include/haproxy/channel-t.h
src/applet.c
src/cli.c
src/stconn.c
src/stream.c

index b87005319755bd71c60bfac58308b472e9bf95e0..56385ebd10e66d28addaf1903a0ae971006ff508 100644 (file)
 #define CF_READ_NOEXP     0x00000080  /* producer should not expire */
 
 #define CF_WRITE_EVENT    0x00000100  /* a write event detected on consumer side */
-#define CF_WRITE_PARTIAL  0x00000200  /* some data were written to the consumer */
+/* unused: 0x00000200 */
 #define CF_WRITE_TIMEOUT  0x00000400  /* timeout while waiting for consumer */
 #define CF_WRITE_ERROR    0x00000800  /* unrecoverable error on consumer side */
-#define CF_WRITE_ACTIVITY (CF_WRITE_EVENT|CF_WRITE_PARTIAL|CF_WRITE_ERROR)
+#define CF_WRITE_ACTIVITY (CF_WRITE_EVENT|CF_WRITE_ERROR)
 
 #define CF_WAKE_WRITE     0x00001000  /* wake the task up when there's write activity */
 #define CF_SHUTW          0x00002000  /* consumer has already shut down */
@@ -140,13 +140,13 @@ static forceinline char *chn_show_flags(char *buf, size_t len, const char *delim
        /* flags */
        _(CF_READ_EVENT, _(CF_READ_TIMEOUT, _(CF_READ_ERROR,
        _(CF_SHUTR, _(CF_SHUTR_NOW, _(CF_READ_NOEXP, _(CF_WRITE_EVENT,
-       _(CF_WRITE_PARTIAL, _(CF_WRITE_TIMEOUT, _(CF_WRITE_ERROR,
+       _(CF_WRITE_TIMEOUT, _(CF_WRITE_ERROR,
        _(CF_WAKE_WRITE, _(CF_SHUTW, _(CF_SHUTW_NOW, _(CF_AUTO_CLOSE,
        _(CF_STREAMER, _(CF_STREAMER_FAST, _(CF_WROTE_DATA, _(CF_ANA_TIMEOUT,
        _(CF_READ_ATTACHED, _(CF_KERN_SPLICING, _(CF_READ_DONTWAIT,
        _(CF_AUTO_CONNECT, _(CF_DONT_READ, _(CF_EXPECT_MORE,
        _(CF_SEND_DONTWAIT, _(CF_NEVER_WAIT, _(CF_WAKE_ONCE, _(CF_FLT_ANALYZE,
-       _(CF_EOI, _(CF_ISRESP))))))))))))))))))))))))))))));
+       _(CF_EOI, _(CF_ISRESP)))))))))))))))))))))))))))));
        /* epilogue */
        _(~0U);
        return buf;
index fedd05c5782aaa48f9a9a93328eb18fafe18f372..7f63c2a1fafdd22920e57c44c20c90d3798d6b73 100644 (file)
@@ -248,7 +248,7 @@ struct task *task_run_applet(struct task *t, void *context, unsigned int state)
         * notify the other side about it.
         */
        if (count != co_data(sc_oc(sc))) {
-               sc_oc(sc)->flags |= CF_WRITE_PARTIAL | CF_WROTE_DATA;
+               sc_oc(sc)->flags |= CF_WRITE_EVENT | CF_WROTE_DATA;
                sc_have_room(sc_opposite(sc));
        }
 
@@ -257,7 +257,7 @@ struct task *task_run_applet(struct task *t, void *context, unsigned int state)
             (b_size(sc_ib(sc)) && !b_data(sc_ib(sc)) && sc->flags & SC_FL_NEED_ROOM) || // asks for room in an empty buffer
             (b_data(sc_ob(sc)) && sc_is_send_allowed(sc)) || // asks for data already present
             (!b_data(sc_ib(sc)) && b_data(sc_ob(sc)) && // didn't return anything ...
-             (sc_oc(sc)->flags & (CF_WRITE_PARTIAL|CF_SHUTW_NOW)) == CF_SHUTW_NOW))) { // ... and left data pending after a shut
+             (sc_oc(sc)->flags & (CF_WRITE_EVENT|CF_SHUTW_NOW)) == CF_SHUTW_NOW))) { // ... and left data pending after a shut
                rate = update_freq_ctr(&app->call_rate, 1);
                if (rate >= 100000 && app->call_rate.prev_ctr) // looped like this more than 100k times over last second
                        stream_dump_and_crash(&app->obj_type, read_freq_ctr(&app->call_rate));
index 0d78e2de5b4e205134762f9ac2f2f933915a8401..0e6bba76b507cf03c8dda7d6b2e503d9048f7c42 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -2785,7 +2785,7 @@ int pcli_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
                sc_set_state(s->scb, SC_ST_INI);
                s->scb->flags &= SC_FL_ISBACK | SC_FL_DONT_WAKE; /* we're in the context of process_stream */
                s->req.flags &= ~(CF_SHUTW|CF_SHUTW_NOW|CF_AUTO_CONNECT|CF_WRITE_ERROR|CF_STREAMER|CF_STREAMER_FAST|CF_NEVER_WAIT|CF_WROTE_DATA);
-               s->res.flags &= ~(CF_SHUTR|CF_SHUTR_NOW|CF_READ_ATTACHED|CF_READ_ERROR|CF_READ_NOEXP|CF_STREAMER|CF_STREAMER_FAST|CF_WRITE_PARTIAL|CF_NEVER_WAIT|CF_WROTE_DATA|CF_READ_EVENT);
+               s->res.flags &= ~(CF_SHUTR|CF_SHUTR_NOW|CF_READ_ATTACHED|CF_READ_ERROR|CF_READ_NOEXP|CF_STREAMER|CF_STREAMER_FAST|CF_WRITE_EVENT|CF_NEVER_WAIT|CF_WROTE_DATA|CF_READ_EVENT);
                s->flags &= ~(SF_DIRECT|SF_ASSIGNED|SF_BE_ASSIGNED|SF_FORCE_PRST|SF_IGNORE_PRST);
                s->flags &= ~(SF_CURR_SESS|SF_REDIRECTABLE|SF_SRV_REUSED);
                s->flags &= ~(SF_ERR_MASK|SF_FINST_MASK|SF_REDISP);
index 2238f1d51609ce60fb6a972f87dfda05652de3ae..18766867cee87a4e39e788baa1491eac9ab1dccc 100644 (file)
@@ -830,7 +830,7 @@ static void sc_app_chk_snd_conn(struct stconn *sc)
                struct channel *ic = sc_ic(sc);
 
                /* update timeout if we have written something */
-               if ((oc->flags & (CF_SHUTW|CF_WRITE_PARTIAL)) == CF_WRITE_PARTIAL &&
+               if ((oc->flags & (CF_SHUTW|CF_WRITE_EVENT)) == CF_WRITE_EVENT &&
                    !channel_is_empty(oc))
                        oc->wex = tick_add_ifset(now_ms, oc->wto);
 
@@ -1127,7 +1127,7 @@ static void sc_notify(struct stconn *sc)
 
        /* update OC timeouts and wake the other side up if it's waiting for room */
        if (oc->flags & CF_WRITE_ACTIVITY) {
-               if ((oc->flags & (CF_SHUTW|CF_WRITE_PARTIAL)) == CF_WRITE_PARTIAL &&
+               if ((oc->flags & (CF_SHUTW|CF_WRITE_EVENT)) == CF_WRITE_EVENT &&
                    !channel_is_empty(oc))
                        if (tick_isset(oc->wex))
                                oc->wex = tick_add_ifset(now_ms, oc->wto);
@@ -1204,13 +1204,14 @@ static void sc_notify(struct stconn *sc)
            (ic->flags & CF_READ_ERROR) || sc_ep_test(sc, SE_FL_ERROR) ||
 
            /* changes on the consumption side */
-           (oc->flags & (CF_WRITE_EVENT|CF_WRITE_ERROR)) ||
-           ((oc->flags & CF_WRITE_ACTIVITY) &&
-            ((oc->flags & CF_SHUTW) ||
+           (oc->flags & CF_WRITE_ERROR) ||
+           ((oc->flags & CF_WRITE_EVENT) &&
+            ((sc->state < SC_ST_EST) ||
+             (oc->flags & CF_SHUTW) ||
              (((oc->flags & CF_WAKE_WRITE) ||
-               !(oc->flags & (CF_AUTO_CLOSE|CF_SHUTW_NOW|CF_SHUTW))) &&
-              (sco->state != SC_ST_EST ||
-               (channel_is_empty(oc) && !oc->to_forward)))))) {
+              !(oc->flags & (CF_AUTO_CLOSE|CF_SHUTW_NOW|CF_SHUTW))) &&
+             (sco->state != SC_ST_EST ||
+              (channel_is_empty(oc) && !oc->to_forward)))))) {
                task_wakeup(task, TASK_WOKEN_IO);
        }
        else {
@@ -1760,7 +1761,7 @@ static int sc_conn_send(struct stconn *sc)
 
  end:
        if (did_send) {
-               oc->flags |= CF_WRITE_PARTIAL | CF_WROTE_DATA;
+               oc->flags |= CF_WRITE_EVENT | CF_WROTE_DATA;
                if (sc->state == SC_ST_CON)
                        sc->state = SC_ST_RDY;
 
@@ -1779,15 +1780,15 @@ static int sc_conn_send(struct stconn *sc)
        return did_send;
 }
 
-/* perform a synchronous send() for the stream connector. The CF_WRITE_EVENT and
- * CF_WRITE_PARTIAL flags are cleared prior to the attempt, and will possibly
- * be updated in case of success.
+/* perform a synchronous send() for the stream connector. The CF_WRITE_EVENT
+ * flag are cleared prior to the attempt, and will possibly be updated in case
+ * of success.
  */
 void sc_conn_sync_send(struct stconn *sc)
 {
        struct channel *oc = sc_oc(sc);
 
-       oc->flags &= ~(CF_WRITE_EVENT|CF_WRITE_PARTIAL);
+       oc->flags &= ~CF_WRITE_EVENT;
 
        if (oc->flags & CF_SHUTW)
                return;
index 79815bd6b766dcee9735840eaf1e50be85150530..0b951ce94c587b1544db2be3e5e04c79ce1ece90 100644 (file)
@@ -1553,8 +1553,8 @@ static void stream_update_both_sc(struct stream *s)
        struct channel *req = &s->req;
        struct channel *res = &s->res;
 
-       req->flags &= ~(CF_READ_EVENT|CF_READ_ATTACHED|CF_WRITE_EVENT|CF_WRITE_PARTIAL);
-       res->flags &= ~(CF_READ_EVENT|CF_READ_ATTACHED|CF_WRITE_EVENT|CF_WRITE_PARTIAL);
+       req->flags &= ~(CF_READ_EVENT|CF_READ_ATTACHED|CF_WRITE_EVENT);
+       res->flags &= ~(CF_READ_EVENT|CF_READ_ATTACHED|CF_WRITE_EVENT);
 
        s->prev_conn_state = scb->state;
 
@@ -1710,7 +1710,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
         * to a bogus analyser or the fact that we're ignoring a read0. The
         * call_rate counter only counts calls with no progress made.
         */
-       if (!((req->flags | res->flags) & (CF_READ_EVENT|CF_WRITE_PARTIAL))) {
+       if (!((req->flags | res->flags) & (CF_READ_EVENT|CF_WRITE_EVENT))) {
                rate = update_freq_ctr(&s->call_rate, 1);
                if (rate >= 100000 && s->call_rate.prev_ctr) // make sure to wait at least a full second
                        stream_dump_and_crash(&s->obj_type, read_freq_ctr(&s->call_rate));