]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: stream-int: replace si_update() with si_update_both()
authorWilly Tarreau <w@1wt.eu>
Thu, 8 Nov 2018 17:15:29 +0000 (18:15 +0100)
committerWilly Tarreau <w@1wt.eu>
Sun, 11 Nov 2018 09:18:37 +0000 (10:18 +0100)
The function used to be called in turn for each side of the stream, but
since it's called exclusively from process_stream(), it prevents us from
making use of the knowledge we have of the operations in progress for
each side, resulting in having to go all the way through functions like
stream_int_notify() which are not appropriate there.

That patch creates a new function, si_update_both() which takes two
stream interfaces expected to belong to the same stream, and processes
their flags in a more suitable order, but for now doesn't change the
logic at all.

The next step will consist in trying to reinsert the rest of the socket
layer-specific update code to ultimately update the flags correctly at
the end of the operation.

include/proto/stream_interface.h
src/stream.c
src/stream_interface.c

index 54d9810f10551763639d2ef0bae43b6f8ff5f047..c8d0a4c3430aa2f1d6819a30960996ab05b2244f 100644 (file)
@@ -56,6 +56,7 @@ void stream_int_notify(struct stream_interface *si);
 int si_cs_recv(struct conn_stream *cs);
 int si_cs_send(struct conn_stream *cs);
 struct task *si_cs_io_cb(struct task *t, void *ctx, unsigned short state);
+void si_update_both(struct stream_interface *si_f, struct stream_interface *si_b);
 
 /* returns the channel which receives data from this stream interface (input channel) */
 static inline struct channel *si_ic(struct stream_interface *si)
index 920c6ad22a14d9995126c445b101b1313c65f5db..b4acc3f758e3545b398fae6096305478a3813158 100644 (file)
@@ -2474,8 +2474,7 @@ redo:
                if ((sess->fe->options & PR_O_CONTSTATS) && (s->flags & SF_BE_ASSIGNED))
                        stream_process_counters(s);
 
-               si_update(si_f);
-               si_update(si_b);
+               si_update_both(si_f, si_b);
 
                if (si_f->state == SI_ST_DIS || si_b->state == SI_ST_DIS ||
                    (((req->flags ^ rqf_last) | (res->flags ^ rpf_last)) & CF_MASK_ANALYSER))
index b29cb2f756430f593595dd39995645a86a6c1945..8d223fabf948166ef83066340bea71903377e81a 100644 (file)
@@ -807,6 +807,40 @@ void stream_int_update(struct stream_interface *si)
        }
 }
 
+/* updates both stream ints of a same stream at once */
+/* Updates at once the channel flags, and timers of both stream interfaces of a
+ * same stream, to complete the work after the analysers, then updates the data
+ * layer below. This will ensure that any synchronous update performed at the
+ * data layer will be reflected in the channel flags and/or stream-interface.
+ */
+void si_update_both(struct stream_interface *si_f, struct stream_interface *si_b)
+{
+       struct channel *req = si_ic(si_f);
+       struct channel *res = si_oc(si_f);
+
+       /* let's recompute both sides states */
+       if (si_f->state == SI_ST_EST)
+               stream_int_update(si_f);
+
+       if (si_b->state == SI_ST_EST)
+               stream_int_update(si_b);
+
+       req->flags &= ~(CF_READ_NULL|CF_READ_PARTIAL|CF_READ_ATTACHED|CF_WRITE_NULL|CF_WRITE_PARTIAL);
+       res->flags &= ~(CF_READ_NULL|CF_READ_PARTIAL|CF_READ_ATTACHED|CF_WRITE_NULL|CF_WRITE_PARTIAL);
+
+       si_f->flags &= ~(SI_FL_ERR|SI_FL_EXP);
+       si_b->flags &= ~(SI_FL_ERR|SI_FL_EXP);
+
+       si_f->prev_state = si_f->state;
+       si_b->prev_state = si_b->state;
+
+       if (si_f->ops->update && si_f->state == SI_ST_EST)
+               si_f->ops->update(si_f);
+
+       if (si_b->ops->update && (si_b->state == SI_ST_EST || si_b->state == SI_ST_CON))
+               si_b->ops->update(si_b);
+}
+
 /* Updates the active status of a connection outside of the connection handler
  * based on the channel's flags and the stream interface's flags. It needs to
  * be called once after the channels' flags have settled down and the stream