]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: stream_interface: pass connection instead of fd in sock_ops
authorWilly Tarreau <wtarreau@exceliance.fr>
Mon, 23 Jul 2012 16:53:03 +0000 (18:53 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 2 Sep 2012 19:53:08 +0000 (21:53 +0200)
The sock_ops I/O callbacks made use of an FD till now. This has become
inappropriate and the struct connection is much more useful. It also
fixes the race condition introduced by previous change.

include/proto/proto_tcp.h
include/types/stream_interface.h
src/connection.c
src/proto_tcp.c
src/sock_raw.c

index 66f29fcdbe53c1c24c9b55fdd1b066a76469925c..6a60121d2191652c3ff7f37d3b6cbd8eac09e125 100644 (file)
@@ -31,7 +31,7 @@ int tcp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct so
 void tcpv4_add_listener(struct listener *listener);
 void tcpv6_add_listener(struct listener *listener);
 int tcp_connect_server(struct stream_interface *si);
-int tcp_connect_probe(int fd);
+int tcp_connect_probe(struct connection *conn);
 int tcp_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir);
 int tcp_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir);
 int tcp_inspect_request(struct session *s, struct buffer *req, int an_bit);
index 88b55abbc79da328d06de207e306abb1c2b33a78..851870fb303960ed9c171b7e4ae4ba1ce84d0e0d 100644 (file)
@@ -114,8 +114,8 @@ struct sock_ops {
        void (*shutw)(struct stream_interface *);   /* shutw function */
        void (*chk_rcv)(struct stream_interface *); /* chk_rcv function */
        void (*chk_snd)(struct stream_interface *); /* chk_snd function */
-       int (*read)(int fd);                        /* read callback after poll() */
-       int (*write)(int fd);                       /* write callback after poll() */
+       int (*read)(struct connection *conn);       /* read callback after poll() */
+       int (*write)(struct connection *conn);      /* write callback after poll() */
        void (*close)(struct connection *);         /* close the data channel on the connection */
 
 };
index 6b84c94e1a1cf6a498da5e03122d1d1678c09889..ef5838ab92d8c6542257e22cc9ea461e5835d43c 100644 (file)
@@ -38,14 +38,14 @@ int conn_fd_handler(int fd)
                        goto leave;
 
        if (fdtab[fd].ev & (FD_POLL_IN | FD_POLL_HUP | FD_POLL_ERR))
-               if (!conn->data->read(fd))
+               if (!conn->data->read(conn))
                        ret |= FD_WAIT_READ;
 
        if (conn->flags & CO_FL_ERROR)
                goto leave;
 
        if (fdtab[fd].ev & (FD_POLL_OUT | FD_POLL_ERR))
-               if (!conn->data->write(fd))
+               if (!conn->data->write(conn))
                        ret |= FD_WAIT_WRITE;
 
        if (conn->flags & CO_FL_ERROR)
@@ -55,7 +55,7 @@ int conn_fd_handler(int fd)
                /* still waiting for a connection to establish and no data to
                 * send in order to probe it ? Then let's retry the connect().
                 */
-               if (!tcp_connect_probe(fd))
+               if (!tcp_connect_probe(conn))
                        ret |= FD_WAIT_WRITE;
        }
 
index 9fb03c44fecfd61a61310d192d23d08961127d99..cebc477107d6894cb3f54adac20478d8b10dcc51 100644 (file)
@@ -524,9 +524,9 @@ int tcp_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir)
  * once the connection is established. It returns zero if it needs some polling
  * before being called again.
  */
-int tcp_connect_probe(int fd)
+int tcp_connect_probe(struct connection *conn)
 {
-       struct connection *conn = fdtab[fd].owner;
+       int fd = conn->t.sock.fd;
        struct stream_interface *si = container_of(conn, struct stream_interface, conn);
        struct buffer *b = si->ob;
        int retval = 0;
index 74ad1277519d41fa4ee8c60262de43019ca183d0..cdb0e271406f7eca10df4d34144eae75a552903d 100644 (file)
@@ -42,8 +42,8 @@
 #include <types/global.h>
 
 /* main event functions used to move data between sockets and buffers */
-static int sock_raw_read(int fd);
-static int sock_raw_write(int fd);
+static int sock_raw_read(struct connection *conn);
+static int sock_raw_write(struct connection *conn);
 static void sock_raw_data_finish(struct stream_interface *si);
 static void sock_raw_shutr(struct stream_interface *si);
 static void sock_raw_shutw(struct stream_interface *si);
@@ -226,9 +226,9 @@ static int sock_raw_splice_in(struct buffer *b, struct stream_interface *si)
  * able to read more data without polling first. Returns non-zero
  * otherwise.
  */
-static int sock_raw_read(int fd)
+static int sock_raw_read(struct connection *conn)
 {
-       struct connection *conn = fdtab[fd].owner;
+       int fd = conn->t.sock.fd;
        struct stream_interface *si = container_of(conn, struct stream_interface, conn);
        struct buffer *b = si->ib;
        int ret, max, retval, cur_read;
@@ -240,9 +240,6 @@ static int sock_raw_read(int fd)
 
        retval = 1;
 
-       if (!conn)
-               goto out_wakeup;
-
        /* stop immediately on errors. Note that we DON'T want to stop on
         * POLL_ERR, as the poller might report a write error while there
         * are still data available in the recv buffer. This typically
@@ -631,9 +628,9 @@ static int sock_raw_write_loop(struct stream_interface *si, struct buffer *b)
  * It returns 0 if the caller needs to poll before calling it again, otherwise
  * non-zero.
  */
-static int sock_raw_write(int fd)
+static int sock_raw_write(struct connection *conn)
 {
-       struct connection *conn = fdtab[fd].owner;
+       int fd = conn->t.sock.fd;
        struct stream_interface *si = container_of(conn, struct stream_interface, conn);
        struct buffer *b = si->ob;
        int retval = 1;
@@ -642,10 +639,6 @@ static int sock_raw_write(int fd)
        fprintf(stderr,"sock_raw_write : fd=%d, owner=%p\n", fd, fdtab[fd].owner);
 #endif
 
-       retval = 1;
-       if (!conn)
-               goto out_wakeup;
-
        if (conn->flags & CO_FL_ERROR)
                goto out_error;