From d898841530c88c6979679a21bf8d4f09fff39f68 Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Tue, 20 Dec 2022 18:10:04 +0100 Subject: [PATCH] MEDIUM: channel: Use CF_WRITE_EVENT instead of CF_WRITE_PARTIAL 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 | 8 ++++---- src/applet.c | 4 ++-- src/cli.c | 2 +- src/stconn.c | 27 ++++++++++++++------------- src/stream.c | 6 +++--- 5 files changed, 24 insertions(+), 23 deletions(-) diff --git a/include/haproxy/channel-t.h b/include/haproxy/channel-t.h index b870053197..56385ebd10 100644 --- a/include/haproxy/channel-t.h +++ b/include/haproxy/channel-t.h @@ -65,10 +65,10 @@ #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; diff --git a/src/applet.c b/src/applet.c index fedd05c578..7f63c2a1fa 100644 --- a/src/applet.c +++ b/src/applet.c @@ -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)); diff --git a/src/cli.c b/src/cli.c index 0d78e2de5b..0e6bba76b5 100644 --- 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); diff --git a/src/stconn.c b/src/stconn.c index 2238f1d516..18766867ce 100644 --- a/src/stconn.c +++ b/src/stconn.c @@ -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; diff --git a/src/stream.c b/src/stream.c index 79815bd6b7..0b951ce94c 100644 --- a/src/stream.c +++ b/src/stream.c @@ -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)); -- 2.39.5