*/
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;
#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 */
#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).
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;
*/
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));
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;
*/
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));
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;
}
}
* 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);
}
}