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 335757e..1dc0512 100644
--- a/include/proto/connection.h
+++ b/include/proto/connection.h
@@ -693,7 +693,7 @@
 	 */
 	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 fa36e8d..51d1015 100644
--- a/include/proto/server.h
+++ b/include/proto/server.h
@@ -244,9 +244,15 @@
 	    !(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])) &&