struct pxcounters be_counters; /* backend statistics counters */
struct pxcounters fe_counters; /* frontend statistics counters */
+ struct list listener_queue; /* list of the temporarily limited listeners because of lack of a proxy resource */
struct stktable table; /* table for storing sticking sessions */
int grace; /* grace time after stop request */
goto do_block;
}
+ /* The proxy is not limited so we can re-enable any waiting listener */
+ if (!LIST_ISEMPTY(&p->listener_queue))
+ dequeue_all_listeners(&p->listener_queue);
+
/* OK we have no reason to block, so let's unblock if we were blocking */
if (p->state == PR_STIDLE) {
for (l = p->listen; l != NULL; l = l->next)
if (!LIST_ISEMPTY(&global_listener_queue))
dequeue_all_listeners(&global_listener_queue);
+ if (!LIST_ISEMPTY(&s->fe->listener_queue))
+ dequeue_all_listeners(&s->fe->listener_queue);
+
if (unlikely((global.mode & MODE_DEBUG) &&
(!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE)))) {
int len;
int max_accept = global.tune.maxaccept;
int cfd;
int ret;
- int loops = 0;
if (unlikely(l->nbconn >= l->maxconn)) {
listener_full(l);
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);
- loops++;
+ 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;
+ }
+
cfd = accept(fd, (struct sockaddr *)&addr, &laddr);
if (unlikely(cfd == -1)) {
switch (errno) {
} /* 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;
}