From 56a77e5933528ae6ccb59c5ef1e03c2a6566adbe Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Sun, 2 Sep 2012 18:34:44 +0200 Subject: [PATCH] MEDIUM: connection: complete the polling cleanups 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 | 7 ------- src/raw_sock.c | 8 ++++---- src/stream_interface.c | 39 ++++++--------------------------------- 3 files changed, 10 insertions(+), 44 deletions(-) diff --git a/include/common/defaults.h b/include/common/defaults.h index 8647131378..b49044e50b 100644 --- a/include/common/defaults.h +++ b/include/common/defaults.h @@ -90,13 +90,6 @@ #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 diff --git a/src/raw_sock.c b/src/raw_sock.c index 80c8fb38d0..ea2fa66846 100644 --- a/src/raw_sock.c +++ b/src/raw_sock.c @@ -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) { diff --git a/src/stream_interface.c b/src/stream_interface.c index b26e800b1c..8d7c24ba68 100644 --- a/src/stream_interface.c +++ b/src/stream_interface.c @@ -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); } /*