From: Willy Tarreau Date: Thu, 5 Dec 2013 01:36:25 +0000 (+0100) Subject: OPTIM: checks: avoid setting SO_LINGER twice X-Git-Tag: v1.5-dev20~158 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2d351b68c20693343433da07ad7bb26dc31161c5;p=thirdparty%2Fhaproxy.git OPTIM: checks: avoid setting SO_LINGER twice We happened to preform this call twice on some checks, once in the recv event handler, and another one in the main function. Remove the one from the event handler which does not make any more sense there. --- diff --git a/src/checks.c b/src/checks.c index 15e667eac7..56f353767d 100644 --- a/src/checks.c +++ b/src/checks.c @@ -1363,12 +1363,6 @@ static void event_srv_chk_r(struct connection *conn) if (conn->xprt && conn->xprt->shutw) conn->xprt->shutw(conn, 0); - if (conn->ctrl && !(conn->flags & CO_FL_SOCK_RD_SH)) { - if (conn->flags & CO_FL_WAIT_RD || !conn->ctrl->drain || !conn->ctrl->drain(conn->t.sock.fd)) - setsockopt(conn->t.sock.fd, SOL_SOCKET, SO_LINGER, - (struct linger *) &nolinger, sizeof(struct linger)); - } - /* OK, let's not stay here forever */ if (check->result & SRV_CHK_FAILED) conn->flags |= CO_FL_ERROR; @@ -1399,20 +1393,21 @@ static int wake_srv_chk(struct connection *conn) */ chk_report_conn_err(conn, errno, 0); + __conn_data_stop_both(conn); + task_wakeup(check->task, TASK_WOKEN_IO); + } + + if (check->result & (SRV_CHK_FAILED|SRV_CHK_PASSED)) { /* We're here because nobody wants to handle the error, so we * sure want to abort the hard way. */ if (conn->ctrl && !(conn->flags & CO_FL_SOCK_RD_SH)) { - setsockopt(conn->t.sock.fd, SOL_SOCKET, SO_LINGER, - (struct linger *) &nolinger, sizeof(struct linger)); + if (conn->flags & CO_FL_WAIT_RD || !conn->ctrl->drain || !conn->ctrl->drain(conn->t.sock.fd)) + setsockopt(conn->t.sock.fd, SOL_SOCKET, SO_LINGER, + (struct linger *) &nolinger, sizeof(struct linger)); } - - __conn_data_stop_both(conn); - task_wakeup(check->task, TASK_WOKEN_IO); - } - - if (check->result & (SRV_CHK_FAILED|SRV_CHK_PASSED)) conn_full_close(conn); + } return 0; } @@ -1621,9 +1616,11 @@ static struct task *process_chk(struct task *t) * as a failed response coupled with "observe layer7" caused the * server state to be suddenly changed. */ - if (conn->ctrl) - setsockopt(conn->t.sock.fd, SOL_SOCKET, SO_LINGER, - (struct linger *) &nolinger, sizeof(struct linger)); + if (conn->ctrl && !(conn->flags & CO_FL_SOCK_RD_SH)) { + if (conn->flags & CO_FL_WAIT_RD || !conn->ctrl->drain || !conn->ctrl->drain(conn->t.sock.fd)) + setsockopt(conn->t.sock.fd, SOL_SOCKET, SO_LINGER, + (struct linger *) &nolinger, sizeof(struct linger)); + } conn_full_close(conn); }