BUG/MINOR: task: Don't defer tasks release when HAProxy is stopping

A running or queued task is not released when task_destroy() is called,
except if it is the current task. Its process function is set to NULL and we
let the scheduler to release the task. However, when HAProxy is stopping, it
never happens and some tasks may leak. To fix the issue, we now also rely on
the global MODE_STOPPING flag. When this flag is set, the task is always
immediately released.

This patch should fix the issue #1714. It could be backported as far as 2.4
but it's not a real problem in practice because it only happens on
deinit. The leak exists on previous versions but not MODE_STOPPING flag.
This commit is contained in:
Christopher Faulet 2022-05-25 09:31:20 +02:00
parent ca82578fe8
commit d9404b464f

View File

@ -609,8 +609,8 @@ static inline void __task_free(struct task *t)
}
/* Destroys a task : it's unlinked from the wait queues and is freed if it's
* the current task or not queued otherwise it's marked to be freed by the
* scheduler. It does nothing if <t> is NULL.
* the current task or not queued or if HAProxy is stopping. Otherwise it's
* marked to be freed by the scheduler. It does nothing if <t> is NULL.
*/
static inline void task_destroy(struct task *t)
{
@ -627,7 +627,7 @@ static inline void task_destroy(struct task *t)
/* There's no need to protect t->state with a lock, as the task
* has to run on the current thread.
*/
if (t == th_ctx->current || !(t->state & (TASK_QUEUED | TASK_RUNNING)))
if (t == th_ctx->current || !(t->state & (TASK_QUEUED | TASK_RUNNING)) || (global.mode & MODE_STOPPING))
__task_free(t);
else
t->process = NULL;