From: Olivier Houchard Date: Fri, 15 Feb 2019 17:49:15 +0000 (+0100) Subject: BUG/MEDIUM: servers: Use atomic operations when handling curr_idle_conns. X-Git-Tag: v2.0-dev1~24 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e737103173d8cc33a564127f9ec442d41ff75a19;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: servers: Use atomic operations when handling curr_idle_conns. Use atomic operations when dealing with srv->curr_idle_conns, as it's shared between threads, otherwise we could get inconsistencies. This should be backported to 1.9. --- diff --git a/include/proto/connection.h b/include/proto/connection.h index 335757ed82..1dc0512f41 100644 --- a/include/proto/connection.h +++ b/include/proto/connection.h @@ -693,7 +693,7 @@ static inline void conn_free(struct connection *conn) */ if (conn->idle_time > 0) { struct server *srv = __objt_server(conn->target); - srv->curr_idle_conns--; + HA_ATOMIC_SUB(&srv->curr_idle_conns, 1); } conn_force_unsubscribe(conn); diff --git a/include/proto/server.h b/include/proto/server.h index fa36e8deb9..51d1015e98 100644 --- a/include/proto/server.h +++ b/include/proto/server.h @@ -244,9 +244,15 @@ static inline int srv_add_to_idle_list(struct server *srv, struct connection *co !(conn->flags & CO_FL_PRIVATE) && ((srv->proxy->options & PR_O_REUSE_MASK) != PR_O_REUSE_NEVR) && !conn->mux->used_streams(conn) && conn->mux->avail_streams(conn)) { + int retadd; + + retadd = HA_ATOMIC_ADD(&srv->curr_idle_conns, 1); + if (retadd >= srv->max_idle_conns) { + HA_ATOMIC_SUB(&srv->curr_idle_conns, 1); + return 0; + } LIST_DEL(&conn->list); LIST_ADDQ(&srv->idle_orphan_conns[tid], &conn->list); - srv->curr_idle_conns++; conn->idle_time = now_ms; if (!(task_in_wq(srv->idle_task[tid])) && diff --git a/src/backend.c b/src/backend.c index 1fd66f932a..3c752a273b 100644 --- a/src/backend.c +++ b/src/backend.c @@ -1343,7 +1343,7 @@ int connect_server(struct stream *s) if (reuse && reuse_orphan) { LIST_DEL(&srv_conn->list); srv_conn->idle_time = 0; - srv->curr_idle_conns--; + HA_ATOMIC_SUB(&srv->curr_idle_conns, 1); LIST_ADDQ(&srv->idle_conns[tid], &srv_conn->list); if (LIST_ISEMPTY(&srv->idle_orphan_conns[tid])) task_unlink_wq(srv->idle_task[tid]);