From 9e272bf95df16b9bfe6713cab0dc510a35e1f8e2 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Wed, 3 Oct 2012 21:04:48 +0200 Subject: [PATCH] MEDIUM: connection: only call the data->wake callback on activity We now check the connection flags for changes in order not to call the data->wake callback when there is no activity. Activity means a change on any of the CO_FL_*_SH, CO_FL_ERROR, CO_FL_CONNECTED, CO_FL_WAIT_CONN* flags, as well as a call to data->recv or data->send. --- include/types/connection.h | 3 +++ src/connection.c | 19 +++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/include/types/connection.h b/include/types/connection.h index 0bcd804f1e..44fdb0d6c8 100644 --- a/include/types/connection.h +++ b/include/types/connection.h @@ -124,6 +124,9 @@ enum { CO_FL_WAIT_L4_CONN = 0x00400000, /* waiting for L4 to be connected */ CO_FL_WAIT_L6_CONN = 0x00800000, /* waiting for L6 to be connected (eg: SSL) */ + /* synthesis of the flags above */ + CO_FL_CONN_STATE = 0x00FF0000, /* all shut/connected flags */ + /*** All the flags below are used for connection handshakes. Any new * handshake should be added after this point, and CO_FL_HANDSHAKE * should be updated. diff --git a/src/connection.c b/src/connection.c index d1813f9675..949e9ccd3e 100644 --- a/src/connection.c +++ b/src/connection.c @@ -29,6 +29,7 @@ int conn_fd_handler(int fd) { struct connection *conn = fdtab[fd].owner; + unsigned int flags; if (unlikely(!conn)) return 0; @@ -36,7 +37,7 @@ int conn_fd_handler(int fd) /* before engaging there, we clear the new WAIT_* flags so that we can * more easily detect an EAGAIN condition from anywhere. */ - conn->flags &= ~(CO_FL_WAIT_DATA|CO_FL_WAIT_ROOM|CO_FL_WAIT_RD|CO_FL_WAIT_WR); + flags = conn->flags &= ~(CO_FL_WAIT_DATA|CO_FL_WAIT_ROOM|CO_FL_WAIT_RD|CO_FL_WAIT_WR); process_handshake: /* The handshake callbacks are called in sequence. If either of them is @@ -77,12 +78,22 @@ int conn_fd_handler(int fd) /* The data transfer starts here and stops on error and handshakes */ if ((fdtab[fd].ev & (FD_POLL_IN | FD_POLL_HUP | FD_POLL_ERR)) && - !(conn->flags & (CO_FL_WAIT_RD|CO_FL_WAIT_ROOM|CO_FL_ERROR|CO_FL_HANDSHAKE))) + !(conn->flags & (CO_FL_WAIT_RD|CO_FL_WAIT_ROOM|CO_FL_ERROR|CO_FL_HANDSHAKE))) { + /* force detection of a flag change : if any I/O succeeds, we're + * forced to have at least one of the CONN_* flags in conn->flags. + */ + flags = 0; conn->data->recv(conn); + } if ((fdtab[fd].ev & (FD_POLL_OUT | FD_POLL_ERR)) && - !(conn->flags & (CO_FL_WAIT_WR|CO_FL_WAIT_DATA|CO_FL_ERROR|CO_FL_HANDSHAKE))) + !(conn->flags & (CO_FL_WAIT_WR|CO_FL_WAIT_DATA|CO_FL_ERROR|CO_FL_HANDSHAKE))) { + /* force detection of a flag change : if any I/O succeeds, we're + * forced to have at least one of the CONN_* flags in conn->flags. + */ + flags = 0; conn->data->send(conn); + } if (unlikely(conn->flags & CO_FL_ERROR)) goto leave; @@ -112,7 +123,7 @@ int conn_fd_handler(int fd) return 0; } - if (conn->flags & CO_FL_WAKE_DATA) + if ((conn->flags & CO_FL_WAKE_DATA) && ((conn->flags ^ flags) & CO_FL_CONN_STATE)) conn->data->wake(conn); /* Last check, verify if the connection just established */ -- 2.39.5