diff --git a/src/stick_table.c b/src/stick_table.c index f4f1de1eb8..b1144661e9 100644 --- a/src/stick_table.c +++ b/src/stick_table.c @@ -378,14 +378,29 @@ void stktable_touch_with_exp(struct stktable *t, struct stksess *ts, int local, { struct eb32_node * eb; int locked = 0; + int old_exp, new_exp; if (expire != HA_ATOMIC_LOAD(&ts->expire)) { /* we'll need to set the expiration and to wake up the expiration timer .*/ HA_ATOMIC_STORE(&ts->expire, expire); if (t->expire) { - if (!locked++) - HA_RWLOCK_WRLOCK(STK_TABLE_LOCK, &t->lock); - t->exp_task->expire = t->exp_next = tick_first(expire, t->exp_next); + /* set both t->exp_next and the task's expire to the newest + * expiration date. + */ + old_exp = HA_ATOMIC_LOAD(&t->exp_next); + do { + new_exp = tick_first(expire, old_exp); + } while (new_exp != old_exp && + !HA_ATOMIC_CAS(&t->exp_next, &old_exp, new_exp) && + __ha_cpu_relax()); + + old_exp = HA_ATOMIC_LOAD(&t->exp_task->expire); + do { + new_exp = HA_ATOMIC_LOAD(&t->exp_next); + } while (new_exp != old_exp && + !HA_ATOMIC_CAS(&t->exp_task->expire, &old_exp, new_exp) && + __ha_cpu_relax()); + task_queue(t->exp_task); /* keep the lock */ }