mirror of
https://github.com/haproxy/haproxy.git
synced 2026-04-21 22:28:41 -04:00
[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.
This commit is contained in:
parent
dd80c6f92d
commit
86491c3164
5 changed files with 17 additions and 9 deletions
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue