REORG: listener: move the global listener queue code to listener.c

The global listener queue code and declarations were still lying in
haproxy.c while not needed there anymore at all. This complicates
the code for no reason. As a result, the global_listener_queue_task
and the global_listener_queue were made static.
This commit is contained in:
Willy Tarreau 2019-12-10 11:18:41 +01:00
parent 241797a3fc
commit a1d97f88e0
3 changed files with 46 additions and 44 deletions

View File

@ -231,8 +231,6 @@ extern int stopping; /* non zero means stopping in progress */
extern int killed; /* >0 means a hard-stop is triggered, >1 means hard-stop immediately */
extern char hostname[MAX_HOSTNAME_LEN];
extern char localpeer[MAX_HOSTNAME_LEN];
extern struct mt_list global_listener_queue; /* list of the temporarily limited listeners */
extern struct task *global_listener_queue_task;
extern unsigned int warned; /* bitfield of a few warnings to emit just once */
extern volatile unsigned long sleeping_thread_mask;
extern struct list proc_list; /* list of process in mworker mode */

View File

@ -235,11 +235,6 @@ unsigned int rlim_fd_max_at_boot = 0;
struct mworker_proc *proc_self = NULL;
/* list of the temporarily limited listeners because of lack of resource */
struct mt_list global_listener_queue = MT_LIST_HEAD_INIT(global_listener_queue);
struct task *global_listener_queue_task;
static struct task *manage_global_listener_queue(struct task *t, void *context, unsigned short state);
static void *run_thread_poll_loop(void *data);
/* bitfield of a few warnings to emit just once (WARN_*) */
@ -1955,15 +1950,6 @@ static void init(int argc, char **argv)
exit(2);
}
global_listener_queue_task = task_new(MAX_THREADS_MASK);
if (!global_listener_queue_task) {
ha_alert("Out of memory when initializing global task\n");
exit(1);
}
/* very simple initialization, users will queue the task if needed */
global_listener_queue_task->context = NULL; /* not even a context! */
global_listener_queue_task->process = manage_global_listener_queue;
/* now we know the buffer size, we can initialize the channels and buffers */
init_buffer();
@ -2597,7 +2583,6 @@ void deinit(void)
free(global.node); global.node = NULL;
free(global.desc); global.desc = NULL;
free(oldpids); oldpids = NULL;
task_destroy(global_listener_queue_task); global_listener_queue_task = NULL;
task_destroy(idle_conn_task);
idle_conn_task = NULL;
@ -2801,33 +2786,6 @@ static void *run_thread_poll_loop(void *data)
return NULL;
}
/* This is the global management task for listeners. It enables listeners waiting
* for global resources when there are enough free resource, or at least once in
* a while. It is designed to be called as a task.
*/
static struct task *manage_global_listener_queue(struct task *t, void *context, unsigned short state)
{
/* 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.
*/
if (unlikely(actconn >= global.maxconn))
goto out;
/* We should periodically try to enable listeners waiting for a global
* resource here, because it is possible, though very unlikely, that
* they have been blocked by a temporary lack of global resource such
* as a file descriptor or memory and that the temporary condition has
* disappeared.
*/
dequeue_all_listeners();
out:
t->expire = TICK_ETERNITY;
task_queue(t);
return t;
}
/* set uid/gid depending on global settings */
static void set_identity(const char *program_name)
{

View File

@ -55,6 +55,12 @@ struct xfer_sock_list *xfer_sock_list = NULL;
*/
static struct work_list *local_listener_queue;
/* list of the temporarily limited listeners because of lack of resource */
static struct mt_list global_listener_queue = MT_LIST_HEAD_INIT(global_listener_queue);
static struct task *global_listener_queue_task;
static struct task *manage_global_listener_queue(struct task *t, void *context, unsigned short state);
#if defined(USE_THREAD)
struct accept_queue_ring accept_queue_rings[MAX_THREADS] __attribute__((aligned(64))) = { };
@ -1144,17 +1150,57 @@ static int listener_queue_init()
ha_alert("Out of memory while initializing listener queues.\n");
return ERR_FATAL|ERR_ABORT;
}
global_listener_queue_task = task_new(MAX_THREADS_MASK);
if (!global_listener_queue_task) {
ha_alert("Out of memory when initializing global listener queue\n");
return ERR_FATAL|ERR_ABORT;
}
/* very simple initialization, users will queue the task if needed */
global_listener_queue_task->context = NULL; /* not even a context! */
global_listener_queue_task->process = manage_global_listener_queue;
return 0;
}
static void listener_queue_deinit()
{
work_list_destroy(local_listener_queue, global.nbthread);
task_destroy(global_listener_queue_task);
global_listener_queue_task = NULL;
}
REGISTER_CONFIG_POSTPARSER("multi-threaded listener queue", listener_queue_init);
REGISTER_POST_DEINIT(listener_queue_deinit);
/* This is the global management task for listeners. It enables listeners waiting
* for global resources when there are enough free resource, or at least once in
* a while. It is designed to be called as a task.
*/
static struct task *manage_global_listener_queue(struct task *t, void *context, unsigned short state)
{
/* 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.
*/
if (unlikely(actconn >= global.maxconn))
goto out;
/* We should periodically try to enable listeners waiting for a global
* resource here, because it is possible, though very unlikely, that
* they have been blocked by a temporary lack of global resource such
* as a file descriptor or memory and that the temporary condition has
* disappeared.
*/
dequeue_all_listeners();
out:
t->expire = TICK_ETERNITY;
task_queue(t);
return t;
}
/*
* Registers the bind keyword list <kwl> as a list of valid keywords for next
* parsing sessions.