diff --git a/include/proto/task.h b/include/proto/task.h index bd2fe4cbb..0177c52ba 100644 --- a/include/proto/task.h +++ b/include/proto/task.h @@ -152,8 +152,11 @@ static inline void task_wakeup(struct task *t, unsigned int f) struct eb_root *root = &task_per_thread[tid].rqueue; #endif - state = HA_ATOMIC_OR(&t->state, f); - if (!(state & TASK_RUNNING)) + f |= TASK_QUEUED; + state = t->state; + while (!HA_ATOMIC_CAS(&t->state, &state, state | f)) + ; + if (!(state & TASK_QUEUED)) __task_wakeup(t, root); } diff --git a/include/types/task.h b/include/types/task.h index e8ade67d6..508667c7b 100644 --- a/include/types/task.h +++ b/include/types/task.h @@ -33,6 +33,7 @@ #define TASK_SLEEPING 0x0000 /* task sleeping */ #define TASK_RUNNING 0x0001 /* the task is currently running */ #define TASK_GLOBAL 0x0002 /* The task is currently in the global runqueue */ +#define TASK_QUEUED 0x0004 /* The task has been (re-)added to the run queue */ #define TASK_WOKEN_INIT 0x0100 /* woken up for initialisation purposes */ #define TASK_WOKEN_TIMER 0x0200 /* woken up because of expired timer */