diff --git a/include/proto/buffers.h b/include/proto/buffers.h index be1c9492a..64427963d 100644 --- a/include/proto/buffers.h +++ b/include/proto/buffers.h @@ -73,7 +73,7 @@ static inline int buffer_isfull(const struct buffer *buf) { */ 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 27d32713d..d8f71188b 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 21c50fc57..806e09e93 100644 --- a/src/proto_uxst.c +++ b/src/proto_uxst.c @@ -717,6 +717,8 @@ void uxst_process_session(struct task *t, int *next) 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 @@ void uxst_process_session(struct task *t, int *next) */ 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 95ece53fa..e163fdfb2 100644 --- a/src/session.c +++ b/src/session.c @@ -556,6 +556,8 @@ void process_session(struct task *t, int *next) 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 @@ resync_stream_interface: */ 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 68471ed17..f04307284 100644 --- a/src/stream_sock.c +++ b/src/stream_sock.c @@ -431,13 +431,12 @@ int stream_sock_write(int fd) { 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 @@ void stream_sock_data_finish(struct stream_interface *si) * 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); } }