return -1;
}
+/* Increment current active connection counter. This ensures that global
+ * maxconn is not reached or exceeded. This must be done for every new frontend
+ * connection allocation.
+ *
+ * Returns the new actconn global value. If maxconn reached or exceeded, 0 is
+ * returned : the connection allocation should be cancelled.
+ */
+int increment_actconn()
+{
+ unsigned int count, next_actconn;
+
+ do {
+ count = actconn;
+ if (unlikely(count >= global.maxconn)) {
+ /* maxconn reached */
+ next_actconn = 0;
+ goto end;
+ }
+
+ /* try to increment actconn */
+ next_actconn = count + 1;
+ } while (!_HA_ATOMIC_CAS(&actconn, (int *)(&count), next_actconn) && __ha_cpu_relax());
+
+ end:
+ return next_actconn;
+}
+
/************************************************************************/
/* All supported sample and ACL keywords must be declared here. */
/************************************************************************/
#include <haproxy/errors.h>
#include <haproxy/fd.h>
#include <haproxy/freq_ctr.h>
+#include <haproxy/frontend.h>
#include <haproxy/global.h>
#include <haproxy/list.h>
#include <haproxy/listener.h>
}
if (!(l->bind_conf->options & BC_O_UNLIMITED)) {
- do {
- count = actconn;
- if (unlikely(count >= global.maxconn)) {
- /* the process was marked full or another
- * thread is going to do it.
- */
- next_actconn = 0;
- expire = tick_add(now_ms, 1000); /* try again in 1 second */
- goto limit_global;
- }
- next_actconn = count + 1;
- } while (!_HA_ATOMIC_CAS(&actconn, (int *)(&count), next_actconn));
+ next_actconn = increment_actconn();
+ if (!next_actconn) {
+ /* the process was marked full or another
+ * thread is going to do it.
+ */
+ expire = tick_add(now_ms, 1000); /* try again in 1 second */
+ goto limit_global;
+ }
}
/* be careful below, the listener might be shutting down in