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 */
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_*) */
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();
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;
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)
{
*/
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))) = { };
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.