From: Willy Tarreau Date: Fri, 17 May 2019 12:16:51 +0000 (+0200) Subject: MINOR: task: always reset curr_task when freeing a task or tasklet X-Git-Tag: v2.0-dev4~67 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=29bf96d73dc7d369cde0d668e24c94f703c0ad32;p=thirdparty%2Fhaproxy.git MINOR: task: always reset curr_task when freeing a task or tasklet With the thread debugger it becomes visible that we can leave some wandering pointers for a while in curr_task, which is inappropriate. This patch addresses this by resetting curr_task to NULL before really freeing the area. This way it becomes safe even regarding signals. --- diff --git a/include/proto/task.h b/include/proto/task.h index 34757f138f..0aea726305 100644 --- a/include/proto/task.h +++ b/include/proto/task.h @@ -319,11 +319,15 @@ static inline struct task *task_new(unsigned long thread_mask) } /* - * Free a task. Its context must have been freed since it will be lost. - * The task count is decremented. + * Free a task. Its context must have been freed since it will be lost. The + * task count is decremented. It it is the current task, this one is reset. */ static inline void __task_free(struct task *t) { + if (t == curr_task) { + curr_task = NULL; + __ha_barrier_store(); + } pool_free(pool_head_task, t); if (unlikely(stopping)) pool_flush(pool_head_task); @@ -363,6 +367,10 @@ static inline void tasklet_free(struct tasklet *tl) _HA_ATOMIC_SUB(&tasks_run_queue, 1); } + if ((struct task *)tl == curr_task) { + curr_task = NULL; + __ha_barrier_store(); + } pool_free(pool_head_tasklet, tl); if (unlikely(stopping)) pool_flush(pool_head_tasklet);