summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilly Tarreau <w@1wt.eu>2020-09-25 11:22:59 +0200
committerWilly Tarreau <w@1wt.eu>2020-10-07 17:27:56 +0200
commit66700022fecd3e54b05fcbdadf13a30c088560f5 (patch)
tree40684897881db4bab0afeb9268f327e698a4d841
parent0f68de2726eaa4b48924cd4a1cb4e09a0293a132 (diff)
downloadhaproxy-66700022fecd3e54b05fcbdadf13a30c088560f5.tar.gz
MEDIUM: listeners: don't bounce listeners management between queues
During 2.1 development, commit f2cb16948 ("BUG/MAJOR: listener: fix thread safety in resume_listener()") was introduced to bounce the enabling/disabling of a listener's FD to one of its threads because the remains of fd_update_cache() were fundamentally incompatible with the need to call fd_want_recv() or fd_stop_recv() for another thread. However since then we've totally dropped such code and it's totally safe to use these functions on an FD that is solely used by another thread (this is even used by the FD migration code). The only remaining limitation concerning the wake up delay was addressed by previous commit "MEDIUM: fd: always wake up one thread when enabling a foreing FD". The current situation forces the FD management to remain in the pause_listener() and resume_listener() functions just so that it can bounce between threads, without having the ability to delegate it to the suitable protocol layer. So let's first remove this now unneeded workaround.
-rw-r--r--src/listener.c37
1 files changed, 0 insertions, 37 deletions
diff --git a/src/listener.c b/src/listener.c
index ecad1f072..4b21f67a4 100644
--- a/src/listener.c
+++ b/src/listener.c
@@ -44,12 +44,6 @@ static struct bind_kw_list bind_keywords = {
.list = LIST_HEAD_INIT(bind_keywords.list)
};
-/* there is one listener queue per thread so that a thread unblocking the
- * global queue can wake up listeners bound only to foreign threads by
- * moving them to the remote queues and waking up the associated tasklet.
- */
-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;
@@ -380,22 +374,11 @@ int resume_listener(struct listener *l)
if (l->state == LI_READY)
goto end;
- MT_LIST_DEL(&l->wait_queue);
-
if (l->maxconn && l->nbconn >= l->maxconn) {
l->state = LI_FULL;
goto end;
}
- if (!(thread_mask(l->rx.settings->bind_thread) & tid_bit)) {
- /* we're not allowed to touch this listener's FD, let's requeue
- * the listener into one of its owning thread's queue instead.
- */
- int first_thread = my_flsl(thread_mask(l->rx.settings->bind_thread) & all_threads_mask) - 1;
- work_list_add(&local_listener_queue[first_thread], &l->wait_queue);
- goto end;
- }
-
fd_want_recv(l->rx.fd);
l->state = LI_READY;
end:
@@ -1110,28 +1093,9 @@ void listener_release(struct listener *l)
dequeue_proxy_listeners(fe);
}
-/* resume listeners waiting in the local listener queue. They are still in LI_LIMITED state */
-static struct task *listener_queue_process(struct task *t, void *context, unsigned short state)
-{
- struct work_list *wl = context;
- struct listener *l;
-
- while ((l = MT_LIST_POP(&wl->head, struct listener *, wait_queue))) {
- /* The listeners are still in the LI_LIMITED state */
- resume_listener(l);
- }
- return t;
-}
-
/* Initializes the listener queues. Returns 0 on success, otherwise ERR_* flags */
static int listener_queue_init()
{
- local_listener_queue = work_list_create(global.nbthread, listener_queue_process, NULL);
- if (!local_listener_queue) {
- 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");
@@ -1146,7 +1110,6 @@ static int listener_queue_init()
static void listener_queue_deinit()
{
- work_list_destroy(local_listener_queue, global.nbthread);
task_destroy(global_listener_queue_task);
global_listener_queue_task = NULL;
}