mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-31 02:22:07 +00:00
MAJOR: get rid of fdtab[].state and use connection->flags instead
fdtab[].state was only used to know whether a connection was in progress or an error was encountered. Instead we now use connection->flags to store a flag for both. This way, connection management will be able to update the connection status on I/O.
This commit is contained in:
parent
900bc93e24
commit
505e34a36d
@ -31,11 +31,6 @@
|
||||
#include <types/task.h>
|
||||
#include <types/protocols.h>
|
||||
|
||||
/* different possible states for the fd */
|
||||
#define FD_STCONN 2
|
||||
#define FD_STREADY 3
|
||||
#define FD_STERROR 4
|
||||
|
||||
enum {
|
||||
DIR_RD=0,
|
||||
DIR_WR=1,
|
||||
@ -74,7 +69,6 @@ struct fdtab {
|
||||
unsigned int s1; /* Position in spec list+1. 0=not in list. */
|
||||
} spec;
|
||||
unsigned short flags; /* various flags precising the exact status of this fd */
|
||||
unsigned char state; /* the state of this fd */
|
||||
unsigned char ev; /* event seen in return of poll() : FD_POLL_* */
|
||||
};
|
||||
|
||||
|
11
src/checks.c
11
src/checks.c
@ -772,8 +772,7 @@ static int event_srv_chk_w(int fd)
|
||||
struct task *t = fdtab[fd].owner;
|
||||
struct server *s = t->context;
|
||||
|
||||
//fprintf(stderr, "event_srv_chk_w, state=%ld\n", unlikely(fdtab[fd].state));
|
||||
if (unlikely(fdtab[fd].state == FD_STERROR || (fdtab[fd].ev & FD_POLL_ERR))) {
|
||||
if (unlikely((s->check_conn->flags & CO_FL_ERROR) || (fdtab[fd].ev & FD_POLL_ERR))) {
|
||||
int skerr, err = errno;
|
||||
socklen_t lskerr = sizeof(skerr);
|
||||
|
||||
@ -888,7 +887,7 @@ static int event_srv_chk_w(int fd)
|
||||
fdtab[fd].ev &= ~FD_POLL_OUT;
|
||||
return 0;
|
||||
out_error:
|
||||
fdtab[fd].state = FD_STERROR;
|
||||
s->check_conn->flags |= CO_FL_ERROR;
|
||||
goto out_wakeup;
|
||||
}
|
||||
|
||||
@ -920,7 +919,7 @@ static int event_srv_chk_r(int fd)
|
||||
int done;
|
||||
unsigned short msglen;
|
||||
|
||||
if (unlikely((s->result & SRV_CHK_ERROR) || (fdtab[fd].state == FD_STERROR))) {
|
||||
if (unlikely((s->result & SRV_CHK_ERROR) || (s->check_conn->flags & CO_FL_ERROR))) {
|
||||
/* in case of TCP only, this tells us if the connection failed */
|
||||
if (!(s->result & SRV_CHK_ERROR))
|
||||
set_server_check_status(s, HCHK_STATUS_SOCKERR, NULL);
|
||||
@ -1232,7 +1231,7 @@ static int event_srv_chk_r(int fd)
|
||||
|
||||
out_wakeup:
|
||||
if (s->result & SRV_CHK_ERROR)
|
||||
fdtab[fd].state = FD_STERROR;
|
||||
s->check_conn->flags |= CO_FL_ERROR;
|
||||
|
||||
/* Reset the check buffer... */
|
||||
*s->check_data = '\0';
|
||||
@ -1461,11 +1460,11 @@ static struct task *process_chk(struct task *t)
|
||||
//fprintf(stderr, "process_chk: 4\n");
|
||||
|
||||
s->curfd = fd; /* that's how we know a test is in progress ;-) */
|
||||
s->check_conn->flags = CO_FL_WAIT_L4_CONN; /* TCP connection pending */
|
||||
fd_insert(fd);
|
||||
fdtab[fd].owner = t;
|
||||
fdtab[fd].cb[DIR_RD].f = &event_srv_chk_r;
|
||||
fdtab[fd].cb[DIR_WR].f = &event_srv_chk_w;
|
||||
fdtab[fd].state = FD_STCONN; /* connection in progress */
|
||||
fdtab[fd].flags = FD_FL_TCP | FD_FL_TCP_NODELAY;
|
||||
EV_FD_SET(fd, DIR_WR); /* for connect status */
|
||||
#ifdef DEBUG_FULL
|
||||
|
@ -1152,6 +1152,7 @@ static struct session *peer_session_create(struct peer *peer, struct peer_sessio
|
||||
s->si[0].conn.peeraddr = NULL;
|
||||
s->si[0].conn.peerlen = 0;
|
||||
s->si[0].conn.t.sock.fd = -1;
|
||||
s->si[0].conn.flags = CO_FL_NONE;
|
||||
s->si[0].owner = t;
|
||||
s->si[0].state = s->si[0].prev_state = SI_ST_EST;
|
||||
s->si[0].err_type = SI_ET_NONE;
|
||||
@ -1172,6 +1173,7 @@ static struct session *peer_session_create(struct peer *peer, struct peer_sessio
|
||||
s->si[1].conn.peeraddr = NULL;
|
||||
s->si[1].conn.peerlen = 0;
|
||||
s->si[1].conn.t.sock.fd = -1; /* just to help with debugging */
|
||||
s->si[1].conn.flags = CO_FL_NONE;
|
||||
s->si[1].owner = t;
|
||||
s->si[1].state = s->si[1].prev_state = SI_ST_ASS;
|
||||
s->si[1].conn_retries = p->conn_retries;
|
||||
|
@ -3823,6 +3823,7 @@ void http_end_txn_clean_session(struct session *s)
|
||||
|
||||
s->req->cons->state = s->req->cons->prev_state = SI_ST_INI;
|
||||
s->req->cons->conn.t.sock.fd = -1; /* just to help with debugging */
|
||||
s->req->cons->conn.flags = CO_FL_NONE;
|
||||
s->req->cons->err_type = SI_ET_NONE;
|
||||
s->req->cons->conn_retries = 0; /* used for logging too */
|
||||
s->req->cons->err_loc = NULL;
|
||||
|
@ -466,8 +466,8 @@ int tcp_connect_server(struct stream_interface *si)
|
||||
si_get_from_addr(si);
|
||||
|
||||
fdtab[fd].owner = si;
|
||||
fdtab[fd].state = FD_STCONN; /* connection in progress */
|
||||
fdtab[fd].flags = FD_FL_TCP | FD_FL_TCP_NODELAY;
|
||||
si->conn.flags = CO_FL_WAIT_L4_CONN; /* connection in progress */
|
||||
|
||||
/* If we have nothing to send, we want to confirm that the TCP
|
||||
* connection is established before doing so, so we use our own write
|
||||
@ -538,10 +538,10 @@ static int tcp_connect_write(int fd)
|
||||
struct buffer *b = si->ob;
|
||||
int retval = 0;
|
||||
|
||||
if (fdtab[fd].state == FD_STERROR)
|
||||
if (si->conn.flags & CO_FL_ERROR)
|
||||
goto out_error;
|
||||
|
||||
if (fdtab[fd].state != FD_STCONN)
|
||||
if (!(si->conn.flags & CO_FL_WAIT_L4_CONN))
|
||||
goto out_ignore; /* strange we were called while ready */
|
||||
|
||||
/* we might have been called just after an asynchronous shutw */
|
||||
@ -618,7 +618,7 @@ static int tcp_connect_write(int fd)
|
||||
*/
|
||||
fdtab[fd].cb[DIR_RD].f = si_data(si)->read;
|
||||
fdtab[fd].cb[DIR_WR].f = si_data(si)->write;
|
||||
fdtab[fd].state = FD_STREADY;
|
||||
si->conn.flags &= ~CO_FL_WAIT_L4_CONN;
|
||||
si->exp = TICK_ETERNITY;
|
||||
return si_data(si)->write(fd);
|
||||
|
||||
@ -637,7 +637,7 @@ static int tcp_connect_write(int fd)
|
||||
* connection retries.
|
||||
*/
|
||||
|
||||
fdtab[fd].state = FD_STERROR;
|
||||
si->conn.flags |= CO_FL_ERROR;
|
||||
fdtab[fd].ev &= ~FD_POLL_STICKY;
|
||||
EV_FD_REM(fd);
|
||||
si->flags |= SI_FL_ERR;
|
||||
@ -654,10 +654,10 @@ static int tcp_connect_read(int fd)
|
||||
|
||||
retval = 1;
|
||||
|
||||
if (fdtab[fd].state == FD_STERROR)
|
||||
if (si->conn.flags & CO_FL_ERROR)
|
||||
goto out_error;
|
||||
|
||||
if (fdtab[fd].state != FD_STCONN) {
|
||||
if (!(si->conn.flags & CO_FL_WAIT_L4_CONN)) {
|
||||
retval = 0;
|
||||
goto out_ignore; /* strange we were called while ready */
|
||||
}
|
||||
@ -680,7 +680,7 @@ static int tcp_connect_read(int fd)
|
||||
* connection retries.
|
||||
*/
|
||||
|
||||
fdtab[fd].state = FD_STERROR;
|
||||
si->conn.flags |= CO_FL_ERROR;
|
||||
fdtab[fd].ev &= ~FD_POLL_STICKY;
|
||||
EV_FD_REM(fd);
|
||||
si->flags |= SI_FL_ERR;
|
||||
@ -818,7 +818,6 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen)
|
||||
listener->state = LI_LISTEN;
|
||||
|
||||
fdtab[fd].owner = listener; /* reference the listener instead of a task */
|
||||
fdtab[fd].state = 0; /* anything will do, but avoid FD_STERROR */
|
||||
fdtab[fd].flags = FD_FL_TCP | ((listener->options & LI_O_NOLINGER) ? FD_FL_TCP_NOLING : 0);
|
||||
fdtab[fd].cb[DIR_RD].f = listener->proto->accept;
|
||||
fdtab[fd].cb[DIR_WR].f = NULL; /* never called */
|
||||
|
@ -265,7 +265,6 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
|
||||
fdtab[fd].cb[DIR_RD].f = listener->proto->accept;
|
||||
fdtab[fd].cb[DIR_WR].f = NULL; /* never called */
|
||||
fdtab[fd].owner = listener; /* reference the listener instead of a task */
|
||||
fdtab[fd].state = 0; /* anything will do, but avoid FD_STERROR */
|
||||
return ERR_NONE;
|
||||
err_rename:
|
||||
ret = rename(backname, path);
|
||||
|
@ -86,6 +86,7 @@ int session_accept(struct listener *l, int cfd, struct sockaddr_storage *addr)
|
||||
s->term_trace = 0;
|
||||
s->si[0].conn.t.sock.fd = cfd;
|
||||
s->si[0].conn.ctrl = l->proto;
|
||||
s->si[0].conn.flags = CO_FL_NONE;
|
||||
s->si[0].addr.from = *addr;
|
||||
s->si[0].conn.peeraddr = (struct sockaddr *)&s->si[0].addr.from;
|
||||
s->si[0].conn.peerlen = sizeof(s->si[0].addr.from);
|
||||
@ -188,6 +189,7 @@ int session_accept(struct listener *l, int cfd, struct sockaddr_storage *addr)
|
||||
* callbacks will be initialized before attempting to connect.
|
||||
*/
|
||||
s->si[1].conn.t.sock.fd = -1; /* just to help with debugging */
|
||||
s->si[1].conn.flags = CO_FL_NONE;
|
||||
s->si[1].owner = t;
|
||||
s->si[1].state = s->si[1].prev_state = SI_ST_INI;
|
||||
s->si[1].err_type = SI_ET_NONE;
|
||||
@ -279,7 +281,6 @@ int session_accept(struct listener *l, int cfd, struct sockaddr_storage *addr)
|
||||
/* finish initialization of the accepted file descriptor */
|
||||
fd_insert(cfd);
|
||||
fdtab[cfd].owner = &s->si[0];
|
||||
fdtab[cfd].state = FD_STREADY;
|
||||
fdtab[cfd].flags = 0;
|
||||
fdtab[cfd].cb[DIR_RD].f = si_data(&s->si[0])->read;
|
||||
fdtab[cfd].cb[DIR_WR].f = si_data(&s->si[0])->write;
|
||||
|
@ -245,7 +245,7 @@ static int sock_raw_read(int fd)
|
||||
* happens when we send too large a request to a backend server
|
||||
* which rejects it before reading it all.
|
||||
*/
|
||||
if (fdtab[fd].state == FD_STERROR)
|
||||
if (si->conn.flags & CO_FL_ERROR)
|
||||
goto out_error;
|
||||
|
||||
/* stop here if we reached the end of data */
|
||||
@ -323,8 +323,8 @@ static int sock_raw_read(int fd)
|
||||
b_adv(b, fwd);
|
||||
}
|
||||
|
||||
if (fdtab[fd].state == FD_STCONN) {
|
||||
fdtab[fd].state = FD_STREADY;
|
||||
if (si->conn.flags & CO_FL_WAIT_L4_CONN) {
|
||||
si->conn.flags &= ~CO_FL_WAIT_L4_CONN;
|
||||
si->exp = TICK_ETERNITY;
|
||||
}
|
||||
|
||||
@ -503,7 +503,7 @@ static int sock_raw_read(int fd)
|
||||
* connection retries.
|
||||
*/
|
||||
|
||||
fdtab[fd].state = FD_STERROR;
|
||||
si->conn.flags |= CO_FL_ERROR;
|
||||
fdtab[fd].ev &= ~FD_POLL_STICKY;
|
||||
EV_FD_REM(fd);
|
||||
si->flags |= SI_FL_ERR;
|
||||
@ -614,8 +614,8 @@ static int sock_raw_write_loop(struct stream_interface *si, struct buffer *b)
|
||||
}
|
||||
|
||||
if (ret > 0) {
|
||||
if (fdtab[si_fd(si)].state == FD_STCONN) {
|
||||
fdtab[si_fd(si)].state = FD_STREADY;
|
||||
if (si->conn.flags & CO_FL_WAIT_L4_CONN) {
|
||||
si->conn.flags &= ~CO_FL_WAIT_L4_CONN;
|
||||
si->exp = TICK_ETERNITY;
|
||||
}
|
||||
|
||||
@ -676,7 +676,7 @@ static int sock_raw_write(int fd)
|
||||
#endif
|
||||
|
||||
retval = 1;
|
||||
if (fdtab[fd].state == FD_STERROR)
|
||||
if (si->conn.flags & CO_FL_ERROR)
|
||||
goto out_error;
|
||||
|
||||
/* we might have been called just after an asynchronous shutw */
|
||||
@ -750,7 +750,7 @@ static int sock_raw_write(int fd)
|
||||
* connection retries.
|
||||
*/
|
||||
|
||||
fdtab[fd].state = FD_STERROR;
|
||||
si->conn.flags |= CO_FL_ERROR;
|
||||
fdtab[fd].ev &= ~FD_POLL_STICKY;
|
||||
EV_FD_REM(fd);
|
||||
si->flags |= SI_FL_ERR;
|
||||
@ -1013,7 +1013,7 @@ static void sock_raw_chk_snd(struct stream_interface *si)
|
||||
/* Write error on the file descriptor. We mark the FD as STERROR so
|
||||
* that we don't use it anymore and we notify the task.
|
||||
*/
|
||||
fdtab[si_fd(si)].state = FD_STERROR;
|
||||
si->conn.flags |= CO_FL_ERROR;
|
||||
fdtab[si_fd(si)].ev &= ~FD_POLL_STICKY;
|
||||
EV_FD_REM(si_fd(si));
|
||||
si->flags |= SI_FL_ERR;
|
||||
|
Loading…
Reference in New Issue
Block a user