From: Willy Tarreau Date: Thu, 12 Mar 2015 23:32:20 +0000 (+0100) Subject: MEDIUM: connection: make conn_drain() perform more controls X-Git-Tag: v1.6-dev2~335 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f31fb07958fa22566cad2bbab1b16aa3ac0ac3e5;p=thirdparty%2Fhaproxy.git MEDIUM: connection: make conn_drain() perform more controls Currently si_idle_conn_null_cb() has to perform some low-level checks over the file descriptor and the connection configuration that should only belong to conn_drain(). Let's move these controls there. The function now automatically checks for errors and hangups on the file descriptor for example, and disables recv polling if there's no drain function at the control layer. --- diff --git a/include/proto/connection.h b/include/proto/connection.h index 27922f3dbf..f542cb2dbe 100644 --- a/include/proto/connection.h +++ b/include/proto/connection.h @@ -552,17 +552,25 @@ static inline int conn_drain(struct connection *conn) if (!conn_ctrl_ready(conn)) return 1; - if (conn->flags & CO_FL_SOCK_RD_SH) + if (conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH)) return 1; - if (!fd_recv_ready(conn->t.sock.fd)) - return 0; - - if (!conn->ctrl->drain) - return 0; - - if (conn->ctrl->drain(conn->t.sock.fd) <= 0) - return 0; + if (fdtab[conn->t.sock.fd].ev & (FD_POLL_ERR|FD_POLL_HUP)) { + fdtab[conn->t.sock.fd].linger_risk = 0; + } + else { + if (!fd_recv_ready(conn->t.sock.fd)) + return 0; + + /* disable draining if we were called and have no drain function */ + if (!conn->ctrl->drain) { + __conn_data_stop_recv(conn); + return 0; + } + + if (conn->ctrl->drain(conn->t.sock.fd) <= 0) + return 0; + } conn->flags |= CO_FL_SOCK_RD_SH; return 1; diff --git a/src/stream_interface.c b/src/stream_interface.c index 3fc1e56935..8450117c23 100644 --- a/src/stream_interface.c +++ b/src/stream_interface.c @@ -497,20 +497,7 @@ int conn_si_send_proxy(struct connection *conn, unsigned int flag) */ static void si_idle_conn_null_cb(struct connection *conn) { - if (conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH)) - return; - - if (fdtab[conn->t.sock.fd].ev & (FD_POLL_ERR|FD_POLL_HUP)) { - fdtab[conn->t.sock.fd].linger_risk = 0; - conn->flags |= CO_FL_SOCK_RD_SH; - } - else { - conn_drain(conn); - } - - /* disable draining if we were called and have no drain function */ - if (!conn->ctrl->drain) - __conn_data_stop_recv(conn); + conn_drain(conn); } /* Callback to be used by connection I/O handlers when some activity is detected