mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 15:47:01 +02:00
[MINOR] add an expiration flag to the stream_sock_interface
This expiration flag is used to indicate that the timer has expired without having to check it everywhere.
This commit is contained in:
parent
3c6ab2e28d
commit
d7704b5343
@ -33,11 +33,11 @@
|
|||||||
/* main event functions used to move data between sockets and buffers */
|
/* main event functions used to move data between sockets and buffers */
|
||||||
int stream_sock_read(int fd);
|
int stream_sock_read(int fd);
|
||||||
int stream_sock_write(int fd);
|
int stream_sock_write(int fd);
|
||||||
int stream_sock_data_check_timeouts(int fd);
|
|
||||||
int stream_sock_data_update(int fd);
|
int stream_sock_data_update(int fd);
|
||||||
int stream_sock_data_finish(int fd);
|
int stream_sock_data_finish(int fd);
|
||||||
int stream_sock_shutr(struct stream_interface *si);
|
int stream_sock_shutr(struct stream_interface *si);
|
||||||
int stream_sock_shutw(struct stream_interface *si);
|
int stream_sock_shutw(struct stream_interface *si);
|
||||||
|
int stream_sock_check_timeouts(struct stream_interface *si);
|
||||||
|
|
||||||
|
|
||||||
/* This either returns the sockname or the original destination address. Code
|
/* This either returns the sockname or the original destination address. Code
|
||||||
|
@ -56,11 +56,18 @@ enum {
|
|||||||
SI_ET_DATA_ABRT = 0x0200, /* data phase aborted by external cause */
|
SI_ET_DATA_ABRT = 0x0200, /* data phase aborted by external cause */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* flags set after I/O */
|
||||||
|
enum {
|
||||||
|
SI_FL_NONE = 0x0000, /* nothing */
|
||||||
|
SI_FL_EXP = 0x0001, /* timeout has expired */
|
||||||
|
};
|
||||||
|
|
||||||
struct stream_interface {
|
struct stream_interface {
|
||||||
unsigned int state; /* SI_ST* */
|
unsigned int state; /* SI_ST* */
|
||||||
unsigned int prev_state;/* SI_ST*, copy of previous state */
|
unsigned int prev_state;/* SI_ST*, copy of previous state */
|
||||||
void *owner; /* generally a (struct task*) */
|
void *owner; /* generally a (struct task*) */
|
||||||
int fd; /* file descriptor for a stream driver when known */
|
int fd; /* file descriptor for a stream driver when known */
|
||||||
|
unsigned int flags; /* SI_FL_*, must be cleared before I/O */
|
||||||
unsigned int exp; /* wake up time for connect, queue, turn-around, ... */
|
unsigned int exp; /* wake up time for connect, queue, turn-around, ... */
|
||||||
int (*shutr)(struct stream_interface *); /* shutr function */
|
int (*shutr)(struct stream_interface *); /* shutr function */
|
||||||
int (*shutw)(struct stream_interface *); /* shutw function */
|
int (*shutw)(struct stream_interface *); /* shutw function */
|
||||||
|
@ -177,6 +177,7 @@ int event_accept(int fd) {
|
|||||||
s->si[0].shutr = stream_sock_shutr;
|
s->si[0].shutr = stream_sock_shutr;
|
||||||
s->si[0].shutw = stream_sock_shutw;
|
s->si[0].shutw = stream_sock_shutw;
|
||||||
s->si[0].fd = cfd;
|
s->si[0].fd = cfd;
|
||||||
|
s->si[0].flags = SI_FL_NONE;
|
||||||
s->si[0].exp = TICK_ETERNITY;
|
s->si[0].exp = TICK_ETERNITY;
|
||||||
s->cli_fd = cfd;
|
s->cli_fd = cfd;
|
||||||
|
|
||||||
@ -188,6 +189,7 @@ int event_accept(int fd) {
|
|||||||
s->si[1].shutw = stream_sock_shutw;
|
s->si[1].shutw = stream_sock_shutw;
|
||||||
s->si[1].exp = TICK_ETERNITY;
|
s->si[1].exp = TICK_ETERNITY;
|
||||||
s->si[1].fd = -1; /* just to help with debugging */
|
s->si[1].fd = -1; /* just to help with debugging */
|
||||||
|
s->si[1].flags = SI_FL_NONE;
|
||||||
|
|
||||||
s->srv = s->prev_srv = s->srv_conn = NULL;
|
s->srv = s->prev_srv = s->srv_conn = NULL;
|
||||||
s->pend_pos = NULL;
|
s->pend_pos = NULL;
|
||||||
|
@ -659,10 +659,12 @@ void process_session(struct task *t, int *next)
|
|||||||
unsigned int rqf_cli, rpf_cli;
|
unsigned int rqf_cli, rpf_cli;
|
||||||
unsigned int rqf_srv, rpf_srv;
|
unsigned int rqf_srv, rpf_srv;
|
||||||
|
|
||||||
/* Check timeouts only during data phase for now */
|
/* 1: Check timeouts only during data phase for now */
|
||||||
if (unlikely(t->state & TASK_WOKEN_TIMER)) {
|
if (unlikely(t->state & TASK_WOKEN_TIMER)) {
|
||||||
buffer_check_timeouts(s->req);
|
buffer_check_timeouts(s->req);
|
||||||
buffer_check_timeouts(s->rep);
|
buffer_check_timeouts(s->rep);
|
||||||
|
stream_sock_check_timeouts(&s->si[0]);
|
||||||
|
stream_sock_check_timeouts(&s->si[1]);
|
||||||
|
|
||||||
if (unlikely(s->req->flags & (BF_READ_TIMEOUT|BF_WRITE_TIMEOUT))) {
|
if (unlikely(s->req->flags & (BF_READ_TIMEOUT|BF_WRITE_TIMEOUT))) {
|
||||||
if (s->req->flags & BF_READ_TIMEOUT) {
|
if (s->req->flags & BF_READ_TIMEOUT) {
|
||||||
@ -690,7 +692,7 @@ void process_session(struct task *t, int *next)
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if we need to close the write side. This can only happen
|
/* 2: Check if we need to close the write side. This can only happen
|
||||||
* when either SHUTR or EMPTY appears, because WRITE_ENA cannot appear
|
* when either SHUTR or EMPTY appears, because WRITE_ENA cannot appear
|
||||||
* from low level, and neither HIJACK nor SHUTW can disappear from low
|
* from low level, and neither HIJACK nor SHUTW can disappear from low
|
||||||
* level.
|
* level.
|
||||||
@ -705,7 +707,7 @@ void process_session(struct task *t, int *next)
|
|||||||
s->rep->cons->shutw(s->rep->cons);
|
s->rep->cons->shutw(s->rep->cons);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* When a server-side connection is released, we have to
|
/* 3: When a server-side connection is released, we have to
|
||||||
* count it and check for pending connections on this server.
|
* count it and check for pending connections on this server.
|
||||||
*/
|
*/
|
||||||
if (unlikely(s->req->cons->state == SI_ST_CLO &&
|
if (unlikely(s->req->cons->state == SI_ST_CLO &&
|
||||||
@ -907,6 +909,7 @@ void process_session(struct task *t, int *next)
|
|||||||
s->rep->flags &= BF_CLEAR_READ & BF_CLEAR_WRITE & BF_CLEAR_TIMEOUT;
|
s->rep->flags &= BF_CLEAR_READ & BF_CLEAR_WRITE & BF_CLEAR_TIMEOUT;
|
||||||
s->si[0].prev_state = s->si[0].state;
|
s->si[0].prev_state = s->si[0].state;
|
||||||
s->si[1].prev_state = s->si[1].state;
|
s->si[1].prev_state = s->si[1].state;
|
||||||
|
s->si[0].flags = s->si[1].flags = 0;
|
||||||
|
|
||||||
/* Trick: if a request is being waiting for the server to respond,
|
/* Trick: if a request is being waiting for the server to respond,
|
||||||
* and if we know the server can timeout, we don't want the timeout
|
* and if we know the server can timeout, we don't want the timeout
|
||||||
|
@ -534,56 +534,17 @@ int stream_sock_shutr(struct stream_interface *si)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function only has to be called once after a wakeup event during a data
|
* This function only has to be called once after a wakeup event in case of
|
||||||
* phase. It controls the file descriptor's status, as well as read and write
|
* suspected timeout. It controls the stream interface timeouts and sets
|
||||||
* timeouts.
|
* si->flags accordingly. It does NOT close anything, as this timeout may
|
||||||
|
* be used for any purpose. It returns 1 if the timeout fired, otherwise
|
||||||
|
* zero.
|
||||||
*/
|
*/
|
||||||
int stream_sock_data_check_timeouts(int fd)
|
int stream_sock_check_timeouts(struct stream_interface *si)
|
||||||
{
|
{
|
||||||
struct buffer *ib = fdtab[fd].cb[DIR_RD].b;
|
if (tick_is_expired(si->exp, now_ms)) {
|
||||||
struct buffer *ob = fdtab[fd].cb[DIR_WR].b;
|
si->flags |= SI_FL_EXP;
|
||||||
|
return 1;
|
||||||
DPRINTF(stderr,"[%u] %s: fd=%d owner=%p ib=%p, ob=%p, exp(r,w)=%u,%u ibf=%08x obf=%08x ibl=%d obl=%d\n",
|
|
||||||
now_ms, __FUNCTION__,
|
|
||||||
fd, fdtab[fd].owner,
|
|
||||||
ib, ob,
|
|
||||||
ib->rex, ob->wex,
|
|
||||||
ib->flags, ob->flags,
|
|
||||||
ib->l, ob->l);
|
|
||||||
|
|
||||||
/* Read timeout */
|
|
||||||
if (unlikely(!(ib->flags & (BF_SHUTR|BF_READ_TIMEOUT)) && tick_is_expired(ib->rex, now_ms))) {
|
|
||||||
//trace_term(t, TT_HTTP_SRV_12);
|
|
||||||
ib->flags |= BF_READ_TIMEOUT;
|
|
||||||
if (!ob->cons->err_type) {
|
|
||||||
//ob->cons->err_loc = t->srv;
|
|
||||||
ob->cons->err_type = SI_ET_DATA_TO;
|
|
||||||
}
|
|
||||||
buffer_shutr(ib);
|
|
||||||
if (ob->flags & BF_SHUTW) {
|
|
||||||
do_close_and_return:
|
|
||||||
fd_delete(fd);
|
|
||||||
ob->cons->state = SI_ST_CLO;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
EV_FD_CLR(fd, DIR_RD);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write timeout */
|
|
||||||
if (unlikely(!(ob->flags & (BF_SHUTW|BF_WRITE_TIMEOUT)) && tick_is_expired(ob->wex, now_ms))) {
|
|
||||||
//trace_term(t, TT_HTTP_SRV_13);
|
|
||||||
ob->flags |= BF_WRITE_TIMEOUT;
|
|
||||||
if (!ob->cons->err_type) {
|
|
||||||
//ob->cons->err_loc = t->srv;
|
|
||||||
ob->cons->err_type = SI_ET_DATA_TO;
|
|
||||||
}
|
|
||||||
buffer_shutw(ob);
|
|
||||||
if (ib->flags & BF_SHUTR)
|
|
||||||
goto do_close_and_return;
|
|
||||||
|
|
||||||
EV_FD_CLR(fd, DIR_WR);
|
|
||||||
shutdown(fd, SHUT_WR);
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user