[MEDIUM] listeners: queue proxy-bound listeners at the proxy's
All listeners that are limited by a proxy-specific resource are now
queued at the proxy's and not globally. This allows finer-grained
wakeups when releasing resource.
diff --git a/src/stream_sock.c b/src/stream_sock.c
index fa03a62..a0b2c11 100644
--- a/src/stream_sock.c
+++ b/src/stream_sock.c
@@ -1192,7 +1192,6 @@
int max_accept = global.tune.maxaccept;
int cfd;
int ret;
- int loops = 0;
if (unlikely(l->nbconn >= l->maxconn)) {
listener_full(l);
@@ -1201,15 +1200,31 @@
if (p && p->fe_sps_lim) {
int max = freq_ctr_remain(&p->fe_sess_per_sec, p->fe_sps_lim, 0);
+
+ if (unlikely(!max)) {
+ /* frontend accept rate limit was reached */
+ limit_listener(l, &p->listener_queue);
+ return 0;
+ }
+
if (max_accept > max)
max_accept = max;
}
- while ((!p || p->feconn < p->maxconn) && actconn < global.maxconn && max_accept--) {
+ while (max_accept--) {
struct sockaddr_storage addr;
socklen_t laddr = sizeof(addr);
+ if (unlikely(actconn >= global.maxconn)) {
+ limit_listener(l, &global_listener_queue);
+ return 0;
+ }
+
+ if (unlikely(p && p->feconn >= p->maxconn)) {
+ limit_listener(l, &p->listener_queue);
+ return 0;
+ }
+
- loops++;
cfd = accept(fd, (struct sockaddr *)&addr, &laddr);
if (unlikely(cfd == -1)) {
switch (errno) {
@@ -1287,10 +1302,6 @@
} /* end of while (p->feconn < p->maxconn) */
- /* if we did not even enter the loop, we've reached resource limits */
- if (!loops && max_accept)
- limit_listener(l, &global_listener_queue);
-
return 0;
}