]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: connection: complete the polling cleanups
authorWilly Tarreau <w@1wt.eu>
Sun, 2 Sep 2012 16:34:44 +0000 (18:34 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 3 Sep 2012 18:47:35 +0000 (20:47 +0200)
I/O handlers now all use __conn_{sock,data}_{stop,poll,want}_* instead
of returning dummy flags. The code has become slightly simpler because
some tricks such as the MIN_RET_FOR_READ_LOOP are not needed anymore,
and the data handlers which switch to a handshake handler do not need
to disable themselves anymore.

include/common/defaults.h
src/raw_sock.c
src/stream_interface.c

index 86471313784968d44cc59f48155a144490e5afb9..b49044e50bb9469effbc8fede8f58d970201f0b4 100644 (file)
 #define MAX_WRITE_POLL_LOOPS 2
 #endif
 
-// the number of bytes returned by a read below which we will not try to
-// poll the socket again. Generally, return values below the MSS are worthless
-// to try again.
-#ifndef MIN_RET_FOR_READ_LOOP
-#define MIN_RET_FOR_READ_LOOP 1460
-#endif
-
 // The minimum number of bytes to be forwarded that is worth trying to splice.
 // Below 4kB, it's not worth allocating pipes nor pretending to zero-copy.
 #ifndef MIN_SPLICE_FORWARD
index 80c8fb38d08c789892d35b84ae214e0edd4e4b22..ea2fa6684646a956ab3647ac3ae40138ca63dda8 100644 (file)
@@ -118,7 +118,7 @@ int raw_sock_to_pipe(struct connection *conn, struct pipe *pipe, unsigned int co
                                 * which will be able to deal with the situation.
                                 */
                                if (splice_detects_close)
-                                       conn->flags |= CO_FL_WAIT_DATA; /* we know for sure that it's EAGAIN */
+                                       __conn_data_poll_recv(conn); /* we know for sure that it's EAGAIN */
                                break;
                        }
                        else if (errno == ENOSYS || errno == EINVAL) {
@@ -168,7 +168,7 @@ int raw_sock_from_pipe(struct connection *conn, struct pipe *pipe)
 
                if (ret <= 0) {
                        if (ret == 0 || errno == EAGAIN) {
-                               conn->flags |= CO_FL_WAIT_ROOM;
+                               __conn_data_poll_send(conn);
                                break;
                        }
                        else if (errno == EINTR)
@@ -245,7 +245,7 @@ static int raw_sock_to_buf(struct connection *conn, struct buffer *buf, int coun
                        goto read0;
                }
                else if (errno == EAGAIN) {
-                       conn->flags |= CO_FL_WAIT_DATA;
+                       __conn_data_poll_recv(conn);
                        break;
                }
                else if (errno != EINTR) {
@@ -306,7 +306,7 @@ static int raw_sock_from_buf(struct connection *conn, struct buffer *buf, int fl
                }
                else if (ret == 0 || errno == EAGAIN) {
                        /* nothing written, we need to poll for write first */
-                       conn->flags |= CO_FL_WAIT_ROOM;
+                       __conn_data_poll_send(conn);
                        break;
                }
                else if (errno != EINTR) {
index b26e800b1c76398b133bcb7911d030a8737303b4..8d7c24ba687b5fbb7d151b82d62e22d4ec975bbd 100644 (file)
@@ -545,7 +545,6 @@ int conn_si_send_proxy(struct connection *conn, unsigned int flag)
        /* Write error on the file descriptor */
        conn->flags |= CO_FL_ERROR;
        conn->flags &= ~flag;
-       __conn_sock_stop_both(conn);
        return 0;
 
  out_wait:
@@ -671,8 +670,6 @@ static int si_conn_send_loop(struct connection *conn)
        int write_poll = MAX_WRITE_POLL_LOOPS;
        int ret;
 
-       conn->flags &= ~(CO_FL_WAIT_DATA | CO_FL_WAIT_ROOM);
-
        if (b->pipe && conn->data->snd_pipe) {
                ret = conn->data->snd_pipe(conn, b->pipe);
                if (ret > 0)
@@ -685,11 +682,6 @@ static int si_conn_send_loop(struct connection *conn)
 
                if (conn->flags & CO_FL_ERROR)
                        return -1;
-
-               if (conn->flags & CO_FL_WAIT_ROOM) {
-                       __conn_data_poll_send(conn);
-                       return 0;
-               }
        }
 
        /* At this point, the pipe is empty, but we may still have data pending
@@ -701,7 +693,7 @@ static int si_conn_send_loop(struct connection *conn)
        /* when we're in this loop, we already know that there is no spliced
         * data left, and that there are sendable buffered data.
         */
-       while (!(conn->flags & (CO_FL_ERROR | CO_FL_SOCK_WR_SH | CO_FL_DATA_WR_SH | CO_FL_WAIT_DATA | CO_FL_WAIT_ROOM | CO_FL_HANDSHAKE))) {
+       while (!(conn->flags & (CO_FL_ERROR | CO_FL_SOCK_WR_SH | CO_FL_DATA_WR_SH | CO_FL_WAIT_DATA | CO_FL_WAIT_WR | CO_FL_HANDSHAKE))) {
                /* check if we want to inform the kernel that we're interested in
                 * sending more data after this call. We want this if :
                 *  - we're about to close after this last send and want to merge
@@ -742,11 +734,6 @@ static int si_conn_send_loop(struct connection *conn)
        if (conn->flags & CO_FL_ERROR)
                return -1;
 
-       if (conn->flags & CO_FL_WAIT_ROOM) {
-               /* we need to poll before going on */
-               __conn_data_poll_send(&si->conn);
-               return 0;
-       }
        return 0;
 }
 
@@ -992,7 +979,6 @@ void si_conn_recv_cb(struct connection *conn)
                return;
 
        cur_read = 0;
-       conn->flags &= ~(CO_FL_WAIT_DATA | CO_FL_WAIT_ROOM);
 
        /* First, let's see if we may splice data across the channel without
         * using a buffer.
@@ -1036,6 +1022,9 @@ void si_conn_recv_cb(struct connection *conn)
                if (conn->flags & CO_FL_ERROR)
                        goto out_error;
 
+               if (conn->flags & CO_FL_WAIT_ROOM) /* most likely the pipe is full */
+                       si->flags |= SI_FL_WAIT_ROOM;
+
                /* splice not possible (anymore), let's go on on standard copy */
        }
 
@@ -1046,11 +1035,11 @@ void si_conn_recv_cb(struct connection *conn)
                b->pipe = NULL;
        }
 
-       while (!b->pipe && !(conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH | CO_FL_DATA_RD_SH | CO_FL_WAIT_DATA | CO_FL_WAIT_ROOM | CO_FL_HANDSHAKE))) {
+       while (!b->pipe && !(conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH | CO_FL_DATA_RD_SH | CO_FL_WAIT_RD | CO_FL_WAIT_ROOM | CO_FL_HANDSHAKE))) {
                max = bi_avail(b);
 
                if (!max) {
-                       conn->flags |= CO_FL_WAIT_ROOM;
+                       si->flags |= SI_FL_WAIT_ROOM;
                        break;
                }
 
@@ -1154,20 +1143,6 @@ void si_conn_recv_cb(struct connection *conn)
        if (conn->flags & CO_FL_ERROR)
                goto out_error;
 
-       if (conn->flags & CO_FL_WAIT_ROOM) {
-               si->flags |= SI_FL_WAIT_ROOM;
-       }
-       else if (conn->flags & CO_FL_WAIT_DATA) {
-               /* we don't automatically ask for polling if we have
-                * read enough data, as it saves some syscalls with
-                * speculative pollers.
-                */
-               if (cur_read < MIN_RET_FOR_READ_LOOP)
-                       __conn_data_poll_recv(conn);
-               else
-                       __conn_data_want_recv(conn);
-       }
-
        if (conn_data_read0_pending(conn))
                /* connection closed */
                goto out_shutdown_r;
@@ -1186,7 +1161,6 @@ void si_conn_recv_cb(struct connection *conn)
  out_error:
        /* Read error on the connection, report the error and stop I/O */
        conn->flags |= CO_FL_ERROR;
-       __conn_data_stop_both(conn);
 }
 
 /*
@@ -1220,7 +1194,6 @@ void si_conn_send_cb(struct connection *conn)
  out_error:
        /* Write error on the connection, report the error and stop I/O */
        conn->flags |= CO_FL_ERROR;
-       __conn_data_stop_both(conn);
 }
 
 /*