diff --git a/src/listener.c b/src/listener.c index 412af94a1..33a1a9995 100644 --- a/src/listener.c +++ b/src/listener.c @@ -47,6 +47,7 @@ struct bind_kw_list bind_keywords = { /* 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 HA_RWLOCK_T global_listener_rwlock; /* listener status for stats */ const char* li_status_st[LI_STATE_COUNT] = { @@ -1207,7 +1208,9 @@ void listener_accept(struct listener *l) * later than ahead. The listener turns to LI_LIMITED. */ limit_listener(l, &global_listener_queue); + HA_RWLOCK_RDLOCK(LISTENER_LOCK, &global_listener_rwlock); task_schedule(global_listener_queue_task, expire); + HA_RWLOCK_RDUNLOCK(LISTENER_LOCK, &global_listener_rwlock); goto end; limit_proxy: @@ -1257,6 +1260,7 @@ static int listener_queue_init() /* 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; + HA_RWLOCK_INIT(&global_listener_rwlock); return 0; } @@ -1294,7 +1298,9 @@ struct task *manage_global_listener_queue(struct task *t, void *context, unsigne dequeue_all_listeners(); out: + HA_RWLOCK_WRLOCK(LISTENER_LOCK, &global_listener_rwlock); t->expire = TICK_ETERNITY; + HA_RWLOCK_WRUNLOCK(LISTENER_LOCK, &global_listener_rwlock); task_queue(t); return t; }