From: Willy Tarreau Date: Wed, 3 Sep 2008 16:11:02 +0000 (+0200) Subject: [MEDIUM] move QUEUE and TAR timers to stream interfaces X-Git-Tag: v1.3.16-rc1~153 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=35374676796ac384261557d038ff9b0cbee84057;p=thirdparty%2Fhaproxy.git [MEDIUM] move QUEUE and TAR timers to stream interfaces It was not practical to have QUEUE and TAR timers in buffers, as they caused triggering of the timeout flags. Move them to the stream interface where they belong. --- diff --git a/include/types/stream_interface.h b/include/types/stream_interface.h index f976565f9e..cd7fb706a2 100644 --- a/include/types/stream_interface.h +++ b/include/types/stream_interface.h @@ -61,6 +61,7 @@ struct stream_interface { unsigned int prev_state;/* SI_ST*, copy of previous state */ void *owner; /* generally a (struct task*) */ int fd; /* file descriptor for a stream driver when known */ + unsigned int exp; /* wake up time for connect, queue, turn-around, ... */ int (*shutw)(struct stream_interface *); /* shutw function */ struct buffer *ib, *ob; /* input and output buffers */ unsigned int err_type; /* first error detected, one of SI_ET_* */ diff --git a/src/backend.c b/src/backend.c index 16b2cc9dfa..4d855dba1d 100644 --- a/src/backend.c +++ b/src/backend.c @@ -1997,7 +1997,7 @@ int srv_redispatch_connect(struct session *t) return 1; case SRV_STATUS_QUEUED: - t->req->wex = tick_add_ifset(now_ms, t->be->timeout.queue); + t->req->cons->exp = tick_add_ifset(now_ms, t->be->timeout.queue); t->req->cons->state = SI_ST_QUE; /* do nothing else and do not wake any other session up */ return 1; diff --git a/src/client.c b/src/client.c index 953e41ee2c..32e90ba4ed 100644 --- a/src/client.c +++ b/src/client.c @@ -170,19 +170,21 @@ int event_accept(int fd) { s->cli_state = CL_STDATA; s->req = s->rep = NULL; /* will be allocated later */ - s->si[0].state = SI_ST_EST; + s->si[0].state = s->si[0].prev_state = SI_ST_EST; s->si[0].err_type = SI_ET_NONE; s->si[0].err_loc = NULL; s->si[0].owner = t; s->si[0].shutw = stream_sock_shutw; s->si[0].fd = cfd; + s->si[0].exp = TICK_ETERNITY; s->cli_fd = cfd; - s->si[1].state = SI_ST_INI; + s->si[1].state = s->si[1].prev_state = SI_ST_INI; s->si[1].err_type = SI_ET_NONE; s->si[1].err_loc = NULL; s->si[1].owner = t; s->si[1].shutw = stream_sock_shutw; + s->si[1].exp = TICK_ETERNITY; s->si[1].fd = -1; /* just to help with debugging */ s->srv = s->prev_srv = s->srv_conn = NULL; diff --git a/src/proto_http.c b/src/proto_http.c index 09cf587704..0a09b2d1eb 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -671,6 +671,9 @@ void process_session(struct task *t, int *next) if (tick_is_expired(s->req->analyse_exp, now_ms)) s->req->flags |= BF_ANA_TIMEOUT; } + /* Note that we don't check nor indicate if we wake up because + * of a timeout on a stream interface. + */ } /* Check if we need to close the write side. This can only happen @@ -908,6 +911,12 @@ void process_session(struct task *t, int *next) if (s->req->analysers) t->expire = tick_first(t->expire, s->req->analyse_exp); + if (s->si[0].exp) + t->expire = tick_first(t->expire, s->si[0].exp); + + if (s->si[1].exp) + t->expire = tick_first(t->expire, s->si[1].exp); + #ifdef DEBUG_FULL fprintf(stderr, "[%u] queuing with exp=%u req->rex=%u req->wex=%u req->ana_exp=%u rep->rex=%u rep->wex=%u\n", now_ms, t->expire, s->req->rex, s->req->wex, s->req->analyse_exp, s->rep->rex, s->rep->wex); @@ -3613,7 +3622,7 @@ int tcp_connection_status(struct session *t) * time of 1 second. We will wait in the previous if block. */ req->cons->state = SI_ST_TAR; - req->wex = tick_add(now_ms, MS_TO_TICKS(1000)); + req->cons->exp = tick_add(now_ms, MS_TO_TICKS(1000)); return 0; } @@ -3731,7 +3740,7 @@ int stream_sock_assign_server(struct session *t) (t->req->flags & BF_EMPTY || t->be->options & PR_O_ABRT_CLOSE))) { /* give up */ trace_term(t, TT_HTTP_SRV_1); - t->req->wex = TICK_ETERNITY; + t->req->cons->exp = TICK_ETERNITY; // FIXME: should we set rep->MAY_FORWARD ? buffer_shutr(t->rep); @@ -3742,18 +3751,19 @@ int stream_sock_assign_server(struct session *t) return 0; } - if (!tick_is_expired(t->req->wex, now_ms)) + if (!tick_is_expired(t->req->cons->exp, now_ms)) return 0; /* still in turn-around */ t->req->cons->state = SI_ST_INI; + t->req->cons->exp = TICK_ETERNITY; } else if (t->req->cons->state == SI_ST_QUE) { if (t->pend_pos) { /* request still in queue... */ - if (tick_is_expired(t->req->wex, now_ms)) { + if (tick_is_expired(t->req->cons->exp, now_ms)) { /* ... and timeout expired */ trace_term(t, TT_HTTP_SRV_3); - t->req->wex = TICK_ETERNITY; + t->req->cons->exp = TICK_ETERNITY; t->logs.t_queue = tv_ms_elapsed(&t->logs.tv_accept, &now); if (t->srv) t->srv->failed_conns++; @@ -3775,7 +3785,7 @@ int stream_sock_assign_server(struct session *t) (t->req->flags & BF_EMPTY || t->be->options & PR_O_ABRT_CLOSE))) { /* give up */ trace_term(t, TT_HTTP_SRV_1); - t->req->wex = TICK_ETERNITY; + t->req->cons->exp = TICK_ETERNITY; t->logs.t_queue = tv_ms_elapsed(&t->logs.tv_accept, &now); // FIXME: should we set rep->MAY_FORWARD ? @@ -3789,6 +3799,7 @@ int stream_sock_assign_server(struct session *t) } /* The connection is not in the queue anymore */ t->req->cons->state = SI_ST_INI; + t->req->cons->exp = TICK_ETERNITY; } /* we may get here from above */ @@ -3802,7 +3813,6 @@ int stream_sock_assign_server(struct session *t) (t->req->flags & BF_EMPTY || t->be->options & PR_O_ABRT_CLOSE))) { /* give up */ trace_term(t, TT_HTTP_SRV_1); - t->req->wex = TICK_ETERNITY; // FIXME: should we set rep->MAY_FORWARD ? buffer_shutr(t->rep); @@ -3822,7 +3832,6 @@ int stream_sock_assign_server(struct session *t) } trace_term(t, TT_HTTP_SRV_2); - t->req->wex = TICK_ETERNITY; // FIXME: should we set rep->MAY_FORWARD ? buffer_shutr(t->rep); @@ -3866,7 +3875,6 @@ int stream_sock_connect_server(struct session *t) if (t->req->cons->state != SI_ST_CON) { /* it was an error */ trace_term(t, TT_HTTP_SRV_4); - t->req->wex = TICK_ETERNITY; // FIXME: should we set rep->MAY_FORWARD ? buffer_shutr(t->rep);