MEDIUM: stream-int: make si_update() synchronize flag changes before the I/O
With the new synchronous si_cs_send() at the end of process_stream(),
we're seeing re-appear the I/O layer specific part of the stream interface
which is supposed to deal with I/O event subscription. The only difference
is that now we subscribe to I/Os only after having attempted (and failed)
them.
This patch brings a cleanup in this by reintroducing stream_int_update_conn()
with the send code from process_stream(). However this alone would not be
enough because the flags which are cleared afterwards would result in the
loss of the possible events (write events only at the moment). So the flags
clearing and stream-int state updates are also performed inside si_update()
between the generic code and the I/O specific code. This definitely makes
sense as after this call we can simply check again for channel and SI flag
changes and decide to loop once again or not.
diff --git a/src/stream.c b/src/stream.c
index 4e2db45..f33713d 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -1659,7 +1659,6 @@
struct channel *req, *res;
struct stream_interface *si_f, *si_b;
struct conn_stream *cs;
- int ret;
activity[tid].stream++;
@@ -2447,38 +2446,13 @@
if ((sess->fe->options & PR_O_CONTSTATS) && (s->flags & SF_BE_ASSIGNED))
stream_process_counters(s);
- cs = objt_cs(si_f->end);
- ret = 0;
- if (cs && !(cs->conn->flags & CO_FL_ERROR) &&
- !(cs->flags & CS_FL_ERROR) &&
- !(si_oc(si_f)->flags & CF_SHUTW) &&
- !(si_f->wait_event.wait_reason & SUB_CAN_SEND) &&
- co_data(si_oc(si_f)))
- ret = si_cs_send(cs);
- cs = objt_cs(si_b->end);
- if (cs && !(cs->conn->flags & CO_FL_ERROR) &&
- !(cs->flags & CS_FL_ERROR) &&
- !(si_oc(si_b)->flags & CF_SHUTW) &&
- !(si_b->wait_event.wait_reason & SUB_CAN_SEND) &&
- co_data(si_oc(si_b)))
- ret |= si_cs_send(cs);
+ si_update(si_f);
+ si_update(si_b);
- if (ret)
+ if (si_f->state == SI_ST_DIS || si_b->state == SI_ST_DIS ||
+ (((req->flags ^ rqf_last) | (res->flags ^ rpf_last)) & CF_MASK_ANALYSER))
goto redo;
- if (si_f->state == SI_ST_EST)
- si_update(si_f);
-
- if (si_b->state == SI_ST_EST)
- si_update(si_b);
-
- req->flags &= ~(CF_READ_NULL|CF_READ_PARTIAL|CF_WRITE_NULL|CF_WRITE_PARTIAL|CF_READ_ATTACHED);
- res->flags &= ~(CF_READ_NULL|CF_READ_PARTIAL|CF_WRITE_NULL|CF_WRITE_PARTIAL|CF_READ_ATTACHED);
- si_f->prev_state = si_f->state;
- si_b->prev_state = si_b->state;
- si_f->flags &= ~(SI_FL_ERR|SI_FL_EXP);
- si_b->flags &= ~(SI_FL_ERR|SI_FL_EXP);
-
/* Trick: if a request is being waiting for the server to respond,
* and if we know the server can timeout, we don't want the timeout
* to expire on the client side first, but we're still interested