]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MAJOR: get rid of fdtab[].state and use connection->flags instead
authorWilly Tarreau <wtarreau@exceliance.fr>
Fri, 6 Jul 2012 08:17:53 +0000 (10:17 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 2 Sep 2012 19:51:26 +0000 (21:51 +0200)
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.

include/types/fd.h
src/checks.c
src/peers.c
src/proto_http.c
src/proto_tcp.c
src/proto_uxst.c
src/session.c
src/sock_raw.c

index 5d5c5ed8ee799cc0f4a8797eab74df1418ea9643..3b009942c182de5847e88290125f08ecdf996d2f 100644 (file)
 #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_* */
 };
 
index 3bf5ec6edf4936d8795c041ede0ba469c09d5f5c..2c2ee7ef7f0fc7b52a62d0bc896e6e23512e41d0 100644 (file)
@@ -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
index c12dcf6f1986aabafe8b2024b112b0b5c8c0a726..e18b06526e6a201f18396c4f5890fe00dba253e7 100644 (file)
@@ -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;
index 4a02f9160417f6ca865e2b54429641155456a050..08e2c9d80a461e235c71fdfb7a776b169e13c04c 100644 (file)
@@ -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;
index 7da152a0d60a0e6a4de4bacd8a158bfb7f08823f..ddc8269e06f0b0acd5eb51e7e17f581470272b24 100644 (file)
@@ -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 */
index 35e48fd0664ae39d2c715f363154dac29bd70a9f..f63760183f8605a63e03d5096fad25d9a065842f 100644 (file)
@@ -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);
index e839922e396841307afb7dfb6fe0db3c246bbabc..c67d85ec38fdb018dd52bd620eaf545c9bd754bd 100644 (file)
@@ -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;
index 376cd7c801cd57471fb46eba52dbaae3ed80ec07..c561a55107dce26412f9b340464330ccbfcaecc4 100644 (file)
@@ -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;