[MEDIUM] indicate when we don't care about read timeout
Sometimes we don't care about a read timeout, for instance, from the
client when waiting for the server, but we still want the client to
be able to read.
Till now it was done by articially forcing the read timeout to ETERNITY.
But this will cause trouble when we want the low level stream sock to
communicate without waking the session up. So we add a BF_READ_NOEXP
flag to indicate that when the read timeout is to be set, it might
have to be set to ETERNITY.
Since BF_READ_ENA was not used, we replaced this flag.
diff --git a/include/proto/buffers.h b/include/proto/buffers.h
index be1c949..6442796 100644
--- a/include/proto/buffers.h
+++ b/include/proto/buffers.h
@@ -73,7 +73,7 @@
*/
static inline void buffer_check_timeouts(struct buffer *b)
{
- if (likely(!(b->flags & (BF_SHUTR|BF_READ_TIMEOUT|BF_READ_ACTIVITY))) &&
+ if (likely(!(b->flags & (BF_SHUTR|BF_READ_TIMEOUT|BF_READ_ACTIVITY|BF_READ_NOEXP))) &&
unlikely(tick_is_expired(b->rex, now_ms)))
b->flags |= BF_READ_TIMEOUT;
diff --git a/include/types/buffers.h b/include/types/buffers.h
index 27d3271..d8f7118 100644
--- a/include/types/buffers.h
+++ b/include/types/buffers.h
@@ -59,7 +59,7 @@
#define BF_FULL 0x000010 /* buffer cannot accept any more data (l >= rlim-data) */
#define BF_SHUTR 0x000020 /* producer has already shut down */
#define BF_SHUTR_NOW 0x000040 /* the producer must shut down for reads immediately */
-#define BF_READ_ENA 0x000080 /* producer is allowed to feed data into the buffer */
+#define BF_READ_NOEXP 0x000080 /* producer should not expire */
#define BF_WRITE_NULL 0x000100 /* write(0) or connect() succeeded on consumer side */
#define BF_WRITE_PARTIAL 0x000200 /* some data were written to the consumer */
@@ -93,7 +93,7 @@
#define BF_MASK_ANALYSER (BF_READ_ATTACHED|BF_READ_ACTIVITY|BF_READ_TIMEOUT|BF_ANA_TIMEOUT|BF_WRITE_ACTIVITY)
/* Mask for static flags which are not events, but might change during processing */
-#define BF_MASK_STATIC (BF_EMPTY|BF_FULL|BF_HIJACK|BF_WRITE_ENA|BF_READ_ENA|BF_SHUTR|BF_SHUTW|BF_SHUTR_NOW|BF_SHUTW_NOW)
+#define BF_MASK_STATIC (BF_EMPTY|BF_FULL|BF_HIJACK|BF_WRITE_ENA|BF_SHUTR|BF_SHUTW|BF_SHUTR_NOW|BF_SHUTW_NOW)
/* Analysers (buffer->analysers).
diff --git a/src/proto_uxst.c b/src/proto_uxst.c
index 21c50fc..806e09e 100644
--- a/src/proto_uxst.c
+++ b/src/proto_uxst.c
@@ -717,6 +717,8 @@
buffer_check_timeouts(s->rep);
}
+ s->req->flags &= ~BF_READ_NOEXP;
+
/* copy req/rep flags so that we can detect shutdowns */
rqf_last = s->req->flags;
rpf_last = s->rep->flags;
@@ -934,8 +936,10 @@
*/
if ((s->rep->flags & (BF_WRITE_ENA|BF_SHUTR)) == 0 &&
- (tick_isset(s->req->wex) || tick_isset(s->rep->rex)))
+ (tick_isset(s->req->wex) || tick_isset(s->rep->rex))) {
+ s->req->flags |= BF_READ_NOEXP;
s->req->rex = TICK_ETERNITY;
+ }
t->expire = tick_first(tick_first(s->req->rex, s->req->wex),
tick_first(s->rep->rex, s->rep->wex));
diff --git a/src/session.c b/src/session.c
index 95ece53..e163fdf 100644
--- a/src/session.c
+++ b/src/session.c
@@ -556,6 +556,8 @@
buffer_check_timeouts(s->rep);
}
+ s->req->flags &= ~BF_READ_NOEXP;
+
/* copy req/rep flags so that we can detect shutdowns */
rqf_last = s->req->flags;
rpf_last = s->rep->flags;
@@ -954,8 +956,10 @@
*/
if ((s->rep->flags & (BF_WRITE_ENA|BF_SHUTR)) == 0 &&
- (tick_isset(s->req->wex) || tick_isset(s->rep->rex)))
+ (tick_isset(s->req->wex) || tick_isset(s->rep->rex))) {
+ s->req->flags |= BF_READ_NOEXP;
s->req->rex = TICK_ETERNITY;
+ }
t->expire = tick_first(tick_first(s->req->rex, s->req->wex),
tick_first(s->rep->rex, s->rep->wex));
diff --git a/src/stream_sock.c b/src/stream_sock.c
index 68471ed..f043072 100644
--- a/src/stream_sock.c
+++ b/src/stream_sock.c
@@ -431,13 +431,12 @@
if (tick_isset(b->wex) && b->flags & BF_WRITE_PARTIAL) {
b->wex = tick_add_ifset(now_ms, b->wto);
- if (tick_isset(b->wex)) {
+ if (tick_isset(b->wex) & tick_isset(si->ib->rex)) {
/* FIXME: to prevent the client from expiring read timeouts during writes,
* we refresh it. A solution would be to merge read+write timeouts into a
* unique one, although that needs some study particularly on full-duplex
* TCP connections. */
- if (tick_isset(b->rex) && !(b->flags & BF_SHUTR))
- b->rex = b->wex;
+ si->ib->rex = b->wex;
}
}
@@ -561,7 +560,8 @@
* update it if is was not yet set, or if we already got some read status.
*/
EV_FD_COND_S(fd, DIR_RD);
- if (!tick_isset(ib->rex) || ib->flags & BF_READ_ACTIVITY)
+ if (!(ib->flags & BF_READ_NOEXP) &&
+ (!tick_isset(ib->rex) || ib->flags & BF_READ_ACTIVITY))
ib->rex = tick_add_ifset(now_ms, ib->rto);
}
}