]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: task: always reset curr_task when freeing a task or tasklet
authorWilly Tarreau <w@1wt.eu>
Fri, 17 May 2019 12:16:51 +0000 (14:16 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 17 May 2019 15:16:20 +0000 (17:16 +0200)
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.

include/proto/task.h

index 34757f138fd81a4d3d197a0d70a15b814de6c6ca..0aea72630526e4892fe612df8cfc24e2816f5774 100644 (file)
@@ -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);