MINOR: stream-int: replace si_update() with si_update_both()

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.
diff --git a/include/proto/stream_interface.h b/include/proto/stream_interface.h
index 54d9810..c8d0a4c 100644
--- a/include/proto/stream_interface.h
+++ b/include/proto/stream_interface.h
@@ -56,6 +56,7 @@
 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)
diff --git a/src/stream.c b/src/stream.c
index 920c6ad..b4acc3f 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -2474,8 +2474,7 @@
 		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))
diff --git a/src/stream_interface.c b/src/stream_interface.c
index b29cb2f..8d223fa 100644
--- a/src/stream_interface.c
+++ b/src/stream_interface.c
@@ -807,6 +807,40 @@
 	}
 }
 
+/* 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