*/
int disable_all_listeners(struct protocol *proto);
-/* Dequeues all of the listeners waiting for a resource in wait queue <queue>. */
-void dequeue_all_listeners(struct mt_list *list);
+/* Dequeues all listeners waiting for a resource the global wait queue */
+void dequeue_all_listeners();
+
+/* Dequeues all listeners waiting for a resource in proxy <px>'s queue */
+void dequeue_proxy_listeners(struct proxy *px);
/* Must be called with the lock held. Depending on <do_close> value, it does
* what unbind_listener or unbind_listener_no_close should do.
global.maxconn = v;
/* Dequeues all of the listeners waiting for a resource */
- if (!MT_LIST_ISEMPTY(&global_listener_queue))
- dequeue_all_listeners(&global_listener_queue);
+ dequeue_all_listeners();
return 1;
}
*res = v * mul;
/* Dequeues all of the listeners waiting for a resource */
- if (!MT_LIST_ISEMPTY(&global_listener_queue))
- dequeue_all_listeners(&global_listener_queue);
+ dequeue_all_listeners();
return 1;
}
*/
static struct task *manage_global_listener_queue(struct task *t, void *context, unsigned short state)
{
- int next = TICK_ETERNITY;
- /* queue is empty, nothing to do */
- if (MT_LIST_ISEMPTY(&global_listener_queue))
- goto out;
-
/* If there are still too many concurrent connections, let's wait for
* some of them to go away. We don't need to re-arm the timer because
* each of them will scan the queue anyway.
* as a file descriptor or memory and that the temporary condition has
* disappeared.
*/
- dequeue_all_listeners(&global_listener_queue);
+ dequeue_all_listeners();
out:
- t->expire = next;
+ t->expire = TICK_ETERNITY;
task_queue(t);
return t;
}
return ERR_NONE;
}
-/* Dequeues all of the listeners waiting for a resource in wait queue <queue>. */
-void dequeue_all_listeners(struct mt_list *list)
+/* Dequeues all listeners waiting for a resource the global wait queue */
+void dequeue_all_listeners()
{
struct listener *listener;
- while ((listener = MT_LIST_POP(list, struct listener *, wait_queue))) {
+ while ((listener = MT_LIST_POP(&global_listener_queue, struct listener *, wait_queue))) {
+ /* This cannot fail because the listeners are by definition in
+ * the LI_LIMITED state.
+ */
+ resume_listener(listener);
+ }
+}
+
+/* Dequeues all listeners waiting for a resource in proxy <px>'s queue */
+void dequeue_proxy_listeners(struct proxy *px)
+{
+ struct listener *listener;
+
+ while ((listener = MT_LIST_POP(&px->listener_queue, struct listener *, wait_queue))) {
/* This cannot fail because the listeners are by definition in
* the LI_LIMITED state.
*/
resume_listener(l);
/* Dequeues all of the listeners waiting for a resource */
- if (!MT_LIST_ISEMPTY(&global_listener_queue))
- dequeue_all_listeners(&global_listener_queue);
+ dequeue_all_listeners();
if (p && !MT_LIST_ISEMPTY(&p->listener_queue) &&
(!p->fe_sps_lim || freq_ctr_remain(&p->fe_sess_per_sec, p->fe_sps_lim, 0) > 0))
- dequeue_all_listeners(&p->listener_queue);
+ dequeue_proxy_listeners(p);
}
/* Now it's getting tricky. The listener was supposed to be in LI_READY
resume_listener(l);
/* Dequeues all of the listeners waiting for a resource */
- if (!MT_LIST_ISEMPTY(&global_listener_queue))
- dequeue_all_listeners(&global_listener_queue);
+ dequeue_all_listeners();
if (!MT_LIST_ISEMPTY(&fe->listener_queue) &&
(!fe->fe_sps_lim || freq_ctr_remain(&fe->fe_sess_per_sec, fe->fe_sps_lim, 0) > 0))
- dequeue_all_listeners(&fe->listener_queue);
+ dequeue_proxy_listeners(fe);
}
/* resume listeners waiting in the local listener queue. They are still in LI_LIMITED state */
}
/* The proxy is not limited so we can re-enable any waiting listener */
- if (!MT_LIST_ISEMPTY(&p->listener_queue))
- dequeue_all_listeners(&p->listener_queue);
+ dequeue_proxy_listeners(p);
out:
t->expire = next;
task_queue(t);
resume_listener(l);
}
- if (px->maxconn > px->feconn && !MT_LIST_ISEMPTY(&px->listener_queue))
- dequeue_all_listeners(&px->listener_queue);
+ if (px->maxconn > px->feconn)
+ dequeue_proxy_listeners(px);
HA_SPIN_UNLOCK(PROXY_LOCK, &px->lock);